Jump to content

Skyp

uniGUI Subscriber
  • Posts

    76
  • Joined

  • Last visited

Posts posted by Skyp

  1. On 1/22/2023 at 4:10 PM, Hayri ASLAN said:

    Hello 

    We added this our backlog. We will solve this issue in the one of the next builds

    We bypassed this error via TUnulayoutConfig.margin and Anchor in alignmentControl = Server. It's not convenient -(

     

    Spent enough time to solve it somehow normally, tried a System.Classes change the sequence of reading Align and Margins, but this did not lead to anything.

    When calling readState, there is an appeal to VCL.Controls (I could not go there from the call stack under Linux64) and after it all margins disappear (by default 3).

    At the same time, I noticed a strange behavior in Margins.bottom for example (Unigroupbox), the bottom value does not disappear (by default 3), but is re-assigned to the Right, this can be seen in the Unisetbounds handler. 

  2. If VRRP works with hyperServer - I also think it could be a cool explanation in the FAQ on designing large systems, for example:
    http://www.unigui.com/resources/online-documentation/developer-manual - Scalability

    (The issue of multiple DBMS connections is solved in my example PgBouncer)
    Tomorrow morning I will try it 2 masters and one slave. Turn off-turn on . This may be an imitation of VRRP operation..

  3. Hi.

    We want to deploy our application on several datacenters, we are going to use the popular multiIP DNS routing(LoadBalancing) approach used for example in Google or large companies.

    image.png.a97c93cc6417df0c0fd851ed7bca4e46.png
    Ie, when a user sends an NS request, the nearest (one of the IP addresses) is returned to him via DNS, thereby the user will get to one of our datacenters (in Lithuania, Finland, Russia, etc.)..

    In each of the datacenters there are several hyper_server instances with VRRP(keepAlived) – a common IP, if one of the hyper_server instances refuses VIP service, the second instance will be responsible, while it will access the same nodes (slave) the same as the first one.


    Because we plan to use the Rewrite load balancing mod and assign a unique white address to each working node (slave).
    I.e. users come with NS: mydomain.com
    Mydomain.com these are 3 IP addresses (different datacenters):
    {
    1. XXX.XXX.XXX.XXX – Finland(a)
    2. XXX.XXX.XXX.XXX – Lithuania(b)
    3. XXX.XXX.XXX.XXX – Russia ©
    }


    DataCenter #1(a) (for example Finland):
    Common IP master – mydomain.com = XXX.XXX.XXX.XXX – Finland
    {
    Master#1 – keepAlived IP – Active
    Master#2 – keepAlived IP – Reserve
    Master#3 – keepAlived IP – Reserve
    }
    All master servers within the datacenter have the same configuration for working nodes (slave): [server-0], [server-1],[server-2],[server-3]..[server-n]
    In Finland (slave), the nodes will be as follows:
    Slave – subdomain.mydomain.com = XXX.XXX.XXX.XXX – Finland
    {
    Slave #1 - a0.mydomain.com
    Slave #2 – a1.mydomain.com
    Slave #3 – a2.mydomain.com
    Slave #4 – a3.mydomain.com
    ... n
    }

    (If one of the slave servers falls, it's not as scary as if the master falls and the automatic reserve does not rise.)


    Then, of course, there is a VRRP for several PgBouncer (for a single pool of DBMS connections), followed by DBMS clusters with sharding and replication. (with auto-failower)

    All this architecture is not problematic except for one issue:
    Will we be able to organize a hot backup via master hyper_server via VRRP? Did someone do it?

    How to automatically raise another master nearby (with the same IP – VIP)(he will immediately pick up all the nodes(slave VM)), does anyone have experience?

  4. Good afternoon. The Mode-2 documentation doesn't say anything about remote Deployment on Linux in Mode2 (http://www.unigui.com/resources/online-documentation/developer-manual).

    It doesn't seem to work in a Linux cluster.
    I guess this error is related to 

     

    I describe the sequence of steps (Step-By-Step):
    Step 1 (i see fileinfo in Slave Server):

    image.thumb.png.8fa484227dbcb2738b857ed3065241df.png

    Step 3 (i see File info in Master server):

    image.thumb.png.8a4d4b586f1fdcb8b425a0135e194a1d.png

    it's okey..

    Step 4 I'm running services(first the slave, then the master):

    image.thumb.png.a95f6f39da16ce58c69a172c64713ded.png

    And md5

    image.thumb.png.36fa54ed8ca6952ebdc43646de742817.png

    Step 5 (i join in Master Server - /server): 

    image.png.159c37d8f0ffbf0a7507b059d6286e66.png

    image.png.1318e7538ae5420d5f6f9545fb1a2aff.png

    it's ok

    Step 6 (I'm uploading the image to master). Image i changed (recompile)

    image.thumb.png.0249c298bff557166f5af7128db662b3.png

    ... Discard, purge, Active.. 

    image.png.8e4f63de28bdda649e4b5b14fd7f388c.png

    master is active - OK

    image.thumb.png.4e81b7630c761dd643c05ed9f8545c37.png

    Step 7 I'm moving to the Node state 

    image.png.44249749664cbd90d12855decb4de040.png

    it doesn't work =(

    Step 8 - I go again and check the hash files on the master and slave

    image.thumb.png.6b3301d8ad28a8f03291b47751655d2b.png

     

    I see that the master has been updated and the slave has not. 

    Step 9 I don't give up and go to the slave - /server

    image.png.a2edbe0a1d876209ddffdcd294471b1f.png

    oo... 

    Logs (slave):

    image.thumb.png.f935b22f979e85c6b0b4f4a8c584f0a3.png

    when trying to log in, he writes Node is purged! (error 700) 

    What am I doing wrong? for me, this Hyper_server functionality is important

    If you update the slave first and then the master, then the master does not see the slave - (the slave is in the Discarded status), only restarting the slave first and then the master helps

     

    image.png

  5. Hi, I wrote the instructions and within the framework of it I conducted testing on disabling the working node - receiving all sessions on the server (master) and enabling the working node.
    The status of the node(VM) is updated to Active when enabled, but users whom the master should send to this node receive error 503. (Below I have described the Step-by-step sequence of steps)

    Step 1: 

    image.thumb.png.f9f1f514f87daba5463caf5707e125b1.png

    Step 2:

    image.png.5bbe9433dcbb62af85dfb6605067e7de.png

    Step 3 (As if the node is out of order - fine): 

    image.thumb.png.b0292c38bca6afae0c33c44d6a04f8f5.png

    Step 4 (I opened a large number of sessions and the master took them all on himself - that's fine): 

    image.thumb.png.0f40c4e97f91bd296815a8cb7338bea6.png

     

    Step 5 (I started the node😞

    image.thumb.png.52d1d65e5dfa91b41fd0743f14cc5940.png

    Step 6(the master's node status has changed to online - that's fine) :

    image.thumb.png.ccbb9bc690410686cc41110788b1c932.png

    Step 7 (I'm trying to open the interface (from Master)):

    image.thumb.png.4e0bcca07f16199da40ebc2e1dfecd2d.png

     

    I specially reproduced this situation separately and attached Hyper_server logs. I ask for help how to exclude a situation when lifting the server (without restarting the Master) drops the work of a part of the cluster? 

    If, after enabling Node(Service/VM) (step 6), I restart and destroy all threads on the master, then the child node will work correctly and there will be no error 503 - but for this I will have to disconnect all users from the master:

    image.thumb.png.c414d8e5825269444866997dbc7d9a09.png

    Do you have any idea why this is happening?

    Version: 1.90.0.1564

    Logs.zip

  6. Если кому-то актуально. Fix по UniDac Alerter (для Postgres):

    В модуль PgClassesUni.pas 

    в часть uses добавляем модуль: 

    unit PgClassesUni;
    interface
    uses
      system.generics.collections,

    Находим класс TPgSQLNotificationsHandler(PgClassesUni.pas):

     

      TPgSQLNotificationsHandler = class

      private

        FBaseConnection: TPgSQLConnection;

        FConnection: TPgSQLConnection;

        FEvents: array of TEventInfo;

        FThread: TPgSQLNotificationsThread;

        FMainTH: TThread; /// добавляем строчку

    В этом-же классе процедуру: 

    DoOnNotification 

    Переносим на уровень public (декларативная часть)

    Ниже описываем класс потока: 

    TMaintThread = class(TThread)
      strict private
        FQueue: TQueue<TPgSQLNotification>;
        FObj: TPgSQLNotificationsHandler;
      public
        procedure Execute; override;
        property Queue: TQueue<TPgSQLNotification> read FQueue write FQueue;
        property Obj: TPgSQLNotificationsHandler read FObj write FObj;
      end;

    В тело Execute пишем: 

    { TMaintThread }
    
    procedure TMaintThread.Execute;
    var
      li: integer;
      le: TPgSQLNotification;
    begin
      FreeOnTerminate := True;
      while not Terminated do
      begin
        sleep(100);
        if Assigned(FQueue) and Assigned(Obj) then
        begin
          for li := FQueue.Count - 1 downto 0 do
          begin
            le := FQueue.extract;
            Obj.DoOnNotification(le.PID, le.Name, le.Message);
            le.free;
            le:=nil;
          end;
        end;
      end;
        if Assigned(FQueue) then
          FreeAndNil(FQueue);
      Obj := nil;
    end;

    В Destroy добавляем :

    if assigned(FMainTH) then 
     FreeAndNil(FMainTH); 
    
     

    Находим в этом же модуле процедуру: 

    procedure TPgSQLNotificationsHandler.ProcessNotification(const Name: string;

      const PID: integer; const Message: string);

    Заменяем: 

        Notif := TPgSQLNotification.Create;
        Notif.PID := PID;
        Notif.Name := Name;
        Notif.Message := Message;
    {$IFDEF MSWINDOWS}
        PostMessage(hUtilWindow, WM_NOTIFICATION, wParam(GCHandle),
          lParam(AllocGCHandle(Notif)));
    {$ELSE}
        try
          FLastNotification := Notif;
          FThread.Synchronize(DoNotification);
        finally
          FLastNotification := nil;
          Notif.Free;
        end;
    {$ENDIF}

    На вот это: 

        FLastNotification := TPgSQLNotification.Create;
        FLastNotification.PID := PID;
        FLastNotification.Name := name;
        FLastNotification.Message := Message;
        if not Assigned(FMainTH) then
        begin
          FMainTH := TMaintThread.Create(True);
          TMaintThread(FMainTH).Obj := Self;
        end;
        if not Assigned(TMaintThread(FMainTH).Queue) then
          TMaintThread(FMainTH).Queue := TQueue<TPgSQLNotification>.Create;
    
        TMaintThread(FMainTH).Queue.Enqueue(FLastNotification);
        FLastNotification := nil;
    
        if not FMainTH.Started then
          FMainTH.Start;

     

    Наслаждаемся - все работает.

    Причиной ошибки является вызов метода Synchronyze который фризит unigui сервер (ошибка возникает),  этот метод нужен на случай если придёт большое кол-во сообщений (Synchronize - будет дожидаться основной отработки). В фиксе все сообщения отработают по очереди. 

  7. 5 hours ago, Hayri ASLAN said:

    Hello We added this our backlog. We will solve this issue in the one of the next builds

    Right now I can't read Cookies when debugging on Centos (fix - check request access on save cookies) - I understand, in another week I came across the following problems - and solved it through crutches:

     

    I'm already editing the source code of the framework, which is definitely wrong, can I get a quick crutch to solve this problem as well?

    Can the problem be solved only on JS?(I don't have time to wait for a new build anyway)

  8. There is a form on which there is a TvirtualTable (Unidac package) or Tfdmemtable (FireDAC package)(tried both).

    uniDBCheckBox components bound to DataSource:

    image.thumb.png.e83118e1f8e5544fe8d1d19ab550be60.png
    When changing the DataSource, I try to edit adjacent records in the same DataSet (code onAfterEdit): 

    procedure TUFrameTreeRulesF.FFrmStructVTableAfterEdit(DataSet: TDataSet);
      procedure MainUpd;
        procedure UpdateRefresh(aIsEnabled, aIsNotifyInface, aIsNotifyEMail: Boolean; aParentStr: string);
        var
          lvq: TVirtualQuery; /// throught query (localSQL)
          lwherestr: string;
        const
          CDefUpdateParentStr : string = 'UPDATE source SET %s WHERE  (idname=:pname OR idname LIKE :pname2) OR id=:pname;';
      begin
          lwherestr := EmptyStr;
          lvq := TVirtualQuery.Create(nil);
          try
           lvq.SourceDataSets.Add(FFrmStruct.VTable, 'source');
            if FIsEnabledChange then
            begin
              lwherestr := lwherestr + 'isEnabled = :pIsEnabled';
            end;
            if FIsNotifyInfaceChange then
            begin
              lwherestr := ifthen(lwherestr.IsEmpty, EmptyStr, ',') +
                'IsEnableNotifyInface =:pIsEnableNotifyInface';
            end;
            if FIsNotifyEMailChange then
            begin
              lwherestr := ifthen(lwherestr.IsEmpty, EmptyStr, ',') +
                'IsEnabledNotifyEmail=:pIsEnabledNotifyEmail';
            end;
            if not lwherestr.IsEmpty then
            begin
              lvq.sql.Text := Format(CDefUpdateParentStr, [lwherestr]);
              lvq.ParamByName('pname').AsString := aParentStr;
              lvq.ParamByName('pname2').AsString := aParentStr + '%';
              if FIsNotifyEMailChange then
                lvq.ParamByName('pIsEnabledNotifyEmail').AsBoolean :=
                  aIsNotifyEMail;
              if FIsNotifyInfaceChange then
                lvq.ParamByName('pIsEnableNotifyInface').AsBoolean :=
                  aIsNotifyInface;
              if FIsEnabledChange then
                lvq.ParamByName('pIsEnabled').AsBoolean := aIsEnabled;
              lvq.Prepare;
             try
                lvq.Execute;
              except
                on e: exception do
                  lwherestr := e.message; /// check
              end;
            end;
          finally
            if Assigned(lvq) then
              lvq.Destroy;
            lvq := nil;
          end;
        end;
    
      var
        lubookmark: TBookmark;
        lparentid: string;
      begin
          FFrmStruct.VTable.AfterEdit := nil;
          lubookmark := FFrmStruct.VTable.Bookmark;
          FFrmStruct.UDbBuissnesObjectTree.BeginUpdate;
          FFrmStruct.VTable.DisableControls;
          FIsChangeSel := True;
          if not FFrmStruct.VTable.FieldByName('idname').AsString.IsEmpty then
            lparentid := FFrmStruct.VTable.FieldByName('idname').AsString
          else
            lparentid := FFrmStruct.VTable.FieldByName('id').AsString;
          FFrmStruct.VTable.edit;
          UpdateRefresh(UDBChBox.Checked, UDBCBNotifyInface.Checked,
           UDBCheckBoxNotifyEmail.Checked, lparentid);
          FFrmStruct.VTable.post;
          FFrmStruct.UDbBuissnesObjectTree.Refresh;
          FFrmStruct.VTable.EnableControls;
          FFrmStruct.UDbBuissnesObjectTree.EndUpdate;
          FFrmStruct.VTable.AfterEdit := FFrmStructVTableAfterEdit;
         if Assigned(lubookmark) then
         FFrmStruct.VTable.GotoBookmark(lubookmark);
        self.hidemask;
      end;
    
    begin
      self.ShowMask('Обновляю данные...');
      FIsEnabledChange := not FFrmStruct.BeforeIsEnabledChange = UDBChBox.Checked;
      FIsNotifyInfaceChange := not FFrmStruct.BeforeisNotifyChange =
        UDBCBNotifyInface.Checked;
      FIsNotifyEMailChange := not FFrmStruct.BeforeIsNotifyEmail =
        UDBCheckBoxNotifyEmail.Checked;
      MainUpd;
      UBtnApplySetting.Enabled := True;
    end;

    After I get the error : "DataSet not in Edit or Insert mode" =( 

    At the same time, after the error occurred, the DataSet was updated (as expected, the code above worked (it works)). I have an error happening in the UniDbCheckBox.pas module:

    I quickly corrected this via a "crutch" (hack):

    image.png.d249195bd24ad571371fec8004290047.png

     

    Version:  1.90.0.1564 

  9. It is not possible to apply the triton theme,ubuntu, etc. not through the Theme Manager via Refresh, not in the designer. (Refresh doesn't work for some reason). 

    I fix it (Crutch(hack) :

    I put the UniGuiConst.pas module next to the project and changed the Default_EXTHEME to the desired theme and it worked:

    image.png.59701a825a288ccdd1a4b431c6d9f956.png

    Version:  1.90.0.1564 

    PS:

    ReCallLastTheme:=True; (but is not working in Linux (CentOS,RHEL) and works well in Windows).

  10. Я установил значения в Design Time, и он отлично работает, если я строю проект под Windows :

    unMUUKNgo

    wABCfkoEw

    image.thumb.png.62d67d299226eaf50ba9217da1fac373.png

    ,1702261233_image(4).thumb.png.6bd1cb57e28271010131ef7972cafa38.png,

    (StandAlone) В Windows (10) (это нормально):

    2033203311_image(2).png.e70c1da91e2b3b5aab24e35f02fb6fd9.png,

    Ff8PVYsaw

    (StandAlone) в Linux (CentOS 7) (это плохо = ():

    iZivHJrvT

    1002618557_image(3).png.3856889c11d79da607ff0a003926d229.png,

    Что я делаю неправильно? Разве это не работает под Linux? (alignwithmargins - маржа)

    Вер: 1.90.0.1564

     

     

     

  11. Hi. 

    Do not display values in BDGrid.
    Processing fields in a query (q_for_users1) is as follows:
    // Query - good job
     for I := 0 to FieldCount-1 do
             begin
               s:='';
               for j := 0 to pos('.',Field_list)-1 do
                 begin
                      s:=s+Field_list[j];
                 end;
                 for j := pos('.',Field_list)+1 to Length(Field_list) do
                 begin
                      s:=s+Field_list[j];
                 end;
                   with Q_for_users1 do
                   begin
             Fields.Name:=Trim(s);
            fields.DisplayLabel:=Field_list;  // Field_list list of allowed characters
               Fields.Visible:=true;

                           end;
             end;
     
    Anddd insert a Grid:
    -------------------------------------------------------------------------------------------------------------------
      with UniMainModule do
          begin
            DATASOURCEUSER.Enabled := false;
            DATASOURCEUSER.DataSet := Q_for_users1;
            UniMainModule.DATASOURCEUSER.Enabled := true;

          end;
     

     uniSession.AddJS((obj_out as TuniDBgrid).JSName+'.store.suspendEvents();');
             (obj_out as TuniDBgrid).BeginUpdate;

       (obj_out as TuniDBgrid).DataSource := DATASOURCEUSER;
          for i := 0 to Field_list.Count - 1 do
          begin

            if (obj_out is TuniDBgrid) = true then
            begin
              with (obj_out as TuniDBgrid) do
              begin
                (obj_out as TuniDBgrid).Columns.Add;
                //   s:=  unimainmodule.Q_for_users1.fields.Name;
                (obj_out as TuniDBgrid).Columns.Visible := true;
           (obj_out as TuniDBgrid).Columns.FieldName :=Q_for_users1. fields.Name;
                (obj_out as TuniDBgrid).Columns.title.Caption := Field_list;
                (obj_out as TuniDBgrid).Columns.Width := 100;

              end;
            end;
        end;
        (obj_out as TuniDBgrid).endupdate;
             uniSession.AddJS((obj_out as TuniDBgrid).JSName+'.store.resumeEvents();');
            uniSession.AddJS((obj_out as TuniDBgrid).JSName+'.view.refresh();');
        end;

    -------------------------------------------------------------------------------------

     All runs without error but in the Grid cell (their number corresponds to the limit in the query) are empty.  Who faced?

×
×
  • Create New...