#1 2014-09-30 22:38:00

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

[mongodb] Replicaset

Hi AB.

I plan to propose some basic changes to the management of connections to a mongodb in replicaset.

looking at your code I see that you assume that fconnections [0] contains the link to the mongodb primary, and [1..n] to the secondary.

This assumption is not true.
Mongodb, operates internally, or on command, its morphology.

Today, the primary server is 1 and 2, 3, 4 secondary.

But if 1 has problems, it could become the 2 primary and 1 on his return online would become secondary.

So every assumption is wrong.

The solution is to dynamically adapt to these changes.

this function deals with the first connection, switches fconnection so that there is 0 in the primary (not beautiful but functional).

function TMongoClient.Open(const DatabaseName: RawUTF8): TMongoDatabase;
var
 success:boolean;
 n:integer;
 tmpConn:TMongoConnection;
begin
  if self=nil then
   result := nil else
   begin
    result := TMongoDatabase(fDatabases.GetObjectByName(DatabaseName));
     n:=high(fConnections);
     if result=nil then
     begin // not already opened -> try now from primary host
      repeat
       if not fConnections[0].Opened then
        fConnections[0].Open;
       try
        result := TMongoDatabase.Create(Self,DatabaseName);
        success:=true;
       except
        success:=false;

        if n>0 then
        begin
         tmpconn:=Fconnections[0]; // switch connection until works
         Fconnections[0]:=Fconnections[n];
         Fconnections[n]:=tmpConn;
         dec(n);
        end;
       end;
      until success or (n=0);
     end;
    fDatabases.AddObject(DatabaseName,result);
   end;

  if result=nil then
    raise EMongoException.CreateUTF8('%.Open: unknown database "%"',[self,DatabaseName]);
end;

Now we must do the same in the case of exceptions in writing.

procedure TMongoCollection.Insert(const Documents: array of variant;
  Flags: TMongoInsertFlags; NoAcknowledge: boolean);
begin
  Database.Client.Connections[0].SendAndFree(TMongoRequestInsert.Create(
    fFullCollectionName,Documents,Flags),NoAcknowledge);
end;

Here I leave to you to decide where it is best to make the switch.

We could also use the command 'replSetGetStatus' that returns the list of servers in the replicaset indicate whether they are primary and in health.

Offline

#2 2014-10-08 18:18:45

Sabbiolina
Member
Registered: 2014-05-20
Posts: 120

Re: [mongodb] Replicaset

Hi AB,
have you had time to do some testing?

Offline

#3 2014-10-17 16:17:07

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,207
Website

Re: [mongodb] Replicaset

Not yet...
sad

Since we do not use replications, I can not do any test.
If you find out some not too complex, and safe way of handling replicasets, feel free to send some patches.

Offline

Board footer

Powered by FluxBB