Is it possible to sync Sphinx Data via TMS Echo?

Hello,
we're using TMS Sphinx for a Webapplication.
The Database on the Webserver is replicated with TMS Echo to our local Server and vice versa.
Is it possible to include the Sphinx related Tables (or just the sx_Users table) into that replication process?
We want to update and modify tenant_id and user_type locally.

Kind regards,
Christian

Yes.
TMS Echo follows the multi-model design used by TMS Aurelius.

That means that you replicate data of entities belonging to a specific model, it's described in the topic about logging the changes in Echo.

Thus, all you should do is simply tell Echo, in the proper places, that you want to replicate data from Sphinx model.

The name of Sphinx model is Biz.Sphinx, thus to get an explorer object from it just use TMappingExplorer.Get('Biz.Sphinx').

Thanks for the fast reply.

I added

  FEchoSubscriber.SubscribeListeners(TMappingExplorer.Get('Biz.Sphinx'));

and the changes are logged on the server and i can see them in the database.

Locally i receive following Error on synchronisation:

image

I think i have to register the "Biz.Sphinx" but don't know where except in the FEchoSubscriber. Do you have any idea?

Kind regards,
Christian

You also need to specify the explorer of the entities you want to load. What operation are you firing that causes the mentioned exception?

This bit causes the Error:

  if not (Setting.Mode.AsUnicodeString='Lokaler Server') then
    begin
      TEcho(Echo).GetRemoteNode(EchoUrl).Push;
      TEcho(Echo).GetRemoteNode(EchoUrl).Pull;
    end;
    TEcho(Echo).BatchLoad;
    TEcho(Echo).Route;

And this is the procedure which initialises the Echo Server

procedure TServerContainer.StartEchoServer;
var
  EchoModule: TEchoServerModule;
  Pool: IDBConnectionPool;
  NodeManager: IEchoNodeManager;
  Conn: IDBConnection;
begin
  if Assigned(SparkleEchoServer) then
     Exit;

  SparkleEchoServer := THttpSysServer.Create;

  // Echo Server
  Pool := AureliusConnection.GetPoolInterface;
  EchoModule := TEchoServerModule.Create(EchoUrl, Pool);
  SparkleEchoServer.AddModule(EchoModule);

  Echo := TEcho.Create(Pool);
  // Create regular tables and fields of the application
  Conn := Echo.Pool.GetConnection;
//  TDatabaseManager.Update(Conn);
  // Create tables and fields for TMS Echo usage
  TDatabaseManager.Update(Conn, TEcho.Explorer);
  Conn := nil; // Free reference

  // Get the NodeManager instance
  NodeManager := Echo.GetNodeManager;

  // If SelfNode is already defined, no need to define it again
  if NodeManager.SelfNode = nil then
  begin
    // SelfNode is not defined, so let's create a Node instance with the name
    // specified by the DBName property ("client1", "client2", "server" in the case
    // of our demo application. It can be any string value, it just needs
    // to be unique among all other databases being replicated.
    NodeManager.CreateNode(Setting.NodeName.AsUnicodeString);

    // Now define this newly created node as the SelfNode
    NodeManager.DefineSelfNode(Setting.NodeName.AsUnicodeString);
    Echo.GetRemoteNode(EchoUrl).RegisterNode;
  end;


  Timer := TSparkleTimer.Create(
    procedure(Echo: TObject)
    begin
      if FRunningTimer then Exit;
      FRunningTimer := True;
      try
      try
      if (Setting.Mode.AsUnicodeString='Lokaler Server') then
        begin
          TEcho(Echo).GetRemoteNode(EchoUrl).Push;
          TEcho(Echo).GetRemoteNode(EchoUrl).Pull;
        end;
      TEcho(Echo).BatchLoad;
      TEcho(Echo).Route;
      finally
        FRunningTimer := False;
      end;
      except on E: Exception do
        MainForm.ApplicationEvents1Exception(self,E);
      end;
    end,
      Echo, 120000, TTimerType.Periodic);

  if not SparkleEchoServer.IsRunning then SparkleEchoServer.Start;

end;

After some trial and Error here is how it worked for me.
I defined following Explorer:

Var
    EchoMap: TMappingSetup;
    FEchoMappedExplorer:TMappingExplorer;
    EchoMap := TMappingSetup.Create;
    EchoMap.MappedClasses.GetModelClasses('Service70');
    EchoMap.MappedClasses.RegisterClass(TUser);
    EchoMap.MappedClasses.RegisterClass(TDBStorageItem);
    EchoMap.MappedClasses.RegisterClass(TUserToken);
    EchoMap.MappedClasses.RegisterClass(TUserClaim);
    EchoMap.MappedClasses.RegisterClass(TRoleClaim);
    EchoMap.MappedClasses.RegisterClass(TRole);
    EchoMap.MappedClasses.RegisterClass(TUserRole);
    FEchoMappedExplorer := TMappingExplorer.Create(EchoMap);

and replaced the TEcho.Batchload with

TEcho(Echo).BatchLoad(FEchoMappedExplorer);

I tried to add the Sphinx-Model with

EchoMap.MappedClasses.GetModelClasses('Biz.Sphinx');

but that didn't worked, so i had to add every single Entity.
Is that the right approach?

Kind regards,
Christian

You can do that, yes.

But you can also simply call BatchLoad passing the explorer that contains the classes that you want to replicate, it would be:

TEcho(Echo).BatchLoad(TMappingExplorer.Get('Biz.Sphinx'));
1 Like

Thank you very much.

Wish you all Happy Holidays.

Kind Regards,

Christian

1 Like

Happy Holidays to you too!

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.