Jump to content

ioan

Members
  • Content Count

    72
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by ioan


  1. Try something like this:

     

    var
      s: TStream;
    begin
      s := TFileStream.Create('soundfile.mp3', fmCreate);
      try
        IdHttp1.Get(your_file_url, s);
      finally
        s.Free;
      end;
    end;

     

    • Like 1

  2. 4 hours ago, Ian Barker said:

    Servers... plural. That's the problem. If it was a single server that had gone bang, I think it would have been considerably easier. I don't know the full details, but it was a cascade of events and multiple affected servers and hardware.

    I don't buy it, I don't think this is just hardware failure. My conspiracy theory is that it started with hardware failure and then they realized that the backup didn't backup for 20 years.

    No matter what hardware failure you have, it doesn't take two weeks to get it back up and running. 

    kOudr.jpeg

    • Haha 6

  3. I have a situation where one server is responsible for hosting several thousands of files, and multiple other servers require access to these files. These servers may have hundreds of concurrent threads accessing, adding, or deleting files on the shared drive. I have been using a windows shared directory to facilitate this access, but I have experienced issues where the shared directory becomes unresponsive, possibly due to too many simultaneous connections.

    What is the best solution for this scenario?

     

    Thanks!


  4. You could use a thread, something like this:

     

    type
      TMyThread = class(TThread)
      private
        FRet: string;
      protected
        procedure Execute; override;
      published
        property Ret: string read FRet;
      end;
    
      TForm5 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
        procedure HandleThreadTerminate(Sender: TObject);
      end;
    
    var
      Form5: TForm5;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm5.Button1Click(Sender: TObject);
    var
      Thread: TMyThread;
    begin
      Thread := TMyThread.Create(true);
      Thread.FreeOnTerminate := true;
      Thread.OnTerminate := HandleThreadTerminate;
      Thread.Start;
    end;
    
    procedure TForm5.HandleThreadTerminate(Sender: TObject);
    begin
      caption := TMyThread(Sender).Ret;
    end;
    
    { TMyThread }
    
    procedure TMyThread.Execute;
    begin
      if not clientclass.connected then
      begin
        FRet :='';
        exit;
      end;
      clientclass.msgvalid:=false;
      idTCPClient.IOHandler.WriteLn(msg);
    
      while (not Terminated) and (not clientclass.msgvalid) do
      begin
        FRet:=clientclass.msgfromserver;
        TThread.Sleep(0);
      end;
    end;

     


  5. I started from scratch (had in plan to trim some fat anyway) and now I'm accessing the database directly from the TThread, inspired by the example from Embarcadero: 

    https://docwiki.embarcadero.com/RADStudio/Sydney/en/Multithreading_(FireDAC) 

    The service now works very well, no more access violations. 

    I wish I had the time and patience to actually find exactly what exactly caused the problem, but the problem only appeared in production and I was pressed to fix it fast so I pretty much made it from scratch. 

     

     

    • Thanks 1

  6. 12 minutes ago, David Heffernan said:

    madExcept works fine a service for me. But if you have JCL Debug working then that's fine. In which case can you get a proper stack trace? 

    The stack trace I posted is the only thing I get when this access violation occurs. Usually when there is an exception, I get more detailed stack trace, but with this problem, that's the only thing I get.


  7. On 5/29/2022 at 12:29 AM, Dalija Prasnikar said:

    Are you sure it is executed in the context of the main thread? Because that is not what the stack trace says. It shows it is called from within TOutThread.Execute method.

     

    Anyway, whatever the problem is, there is not enough code to determine what is the root cause. Data modules can be constructed in the background threads, but only and only if all components used are thread safe in that regard. In other words if they support being constructed in background thread. How they are configured and what other components are linked as properties also impacts the thread safety.

     

    Additional comment. That application does not have memory leaks is good, but not having memory leaks does not mean that code is thread-safe and that it will run correctly.

    TOutThread is the main thread that starts lots of worker threads. The problem is in the worker threads. The only global variables I'm using are some strings that I initialize at the application start (before any threads are running) with the initial paths and the worker only read the values. All the other components are standard Delphi firedac database access. 

     


  8. I have a multithreaded service that creates a TDataModule for each thread. The DataModule has the logic for some light work on a firebird database.

    My service runs, depending of the hour of the day, between 0 and 300 consecutive threads and about 50-70 thousand total threads in a day. Some threads can be alive for an hour or more, some for few seconds.  Most of the time the threads are just idle, waiting for a file on disk (each thread waits for a file with a specific name, no two threads try to read the same file). 

     

    There are no memory leaks in the service, if I run the service as an application for a whole day in production with the 

    ReportMemoryLeaksOnShutdown := true;

    and there are no leaks reported. 

    There are no threads that remain hanging, after a certain while, they'll terminate automatically if they are alive for too long (a timeout value depending of what the job is). 

     

    The problem is that after a random amount of time of running, the thread creation fails at with Access Violation

    DataModule := TDataModuleMain.Create(nil);

    and when this starts, no more threads can be created, all of them fail at the same line, the line above.

     

    The TThread.Create is as follows:

    constructor TPFXIncomingMessage.Create;
    begin
      inherited Create(true);
      FreeOnTerminate := true;
      DataModule := TDataModuleMain.Create(nil);
      FIsRecovered := false;
    end;

     

    Here is the call stack:

    EAccessViolation: Access violation at address 0000000000921298 in module 'pfxout.exe'. Read of address FFFFFFFFFFFFFFFF
    ----------------------------
    [0000000000F1EB51] JclDebug.TJclStackInfoList.Create + $151
    [0000000000F1E698] JclDebug.JclCreateStackList + $48
    [0000000000F1E5A6] JclDebug.DoExceptionStackTrace + $76
    [0000000000F20BA6] JclDebug.DoExceptNotify + $86
    [0000000000F116C5] JclHookExcept.TNotifierItem.DoNotify + $35
    [0000000000F1190B] JclHookExcept.DoExceptNotify + $BB
    [0000000000F11A65] JclHookExcept.HookedRaiseException + $75
    [00000000008F21D3] System.@RaiseAtExcept + $103
    [00000000008F2238] System.@RaiseAgain + $38
    [00000000015FC969] threaddoit.TPFXIncomingMessage.Create (Line 59, "threaddoit.pas" + 5) + $42
    [00000000015FFC76] outthread.TOutThread.ProcessRecRequest (Line 182, "outthread.pas" + 15) + $E
    [00000000015FF4CB] outthread.TOutThread.Execute (Line 88, "outthread.pas" + 6) + $0
    [0000000000A1A1E3] System.Classes.ThreadProc + $43
    [00000000008F2DAD] System.ThreadWrapper + $3D
    [00007FF95AA713D2] BaseThreadInitThunk + $22
    [00007FF95C455504] RtlUserThreadStart + $34

     

    The service is compiled for 64 bits.

    Before I start modifying everything, trying to fix a problem that I have no idea where it comes from, before trying to rewrite a bunch of code that should work and has no memory leaks, my question is: Are there some kind of rules that I don't know about on creating and freeing so many DataModules? I'm asking this because I had the same problem with a RemObjects SOAP service and the answer I got on the remobjects forum was: 

    it is failed at creating _Impl forms.
    it is weird error and something is happened in delphi’s standard library
    
    

     

    Any ideas or advice?

     

    Thanks.

     


  9. 1 hour ago, Remy Lebeau said:

    Um, because it states that it is a password field?

    
    <input ... TYPE="password" ... />

    I understand that, but what if I want to have some other field with the characters masked, would Chrome automatically assume that any masked field is a password field and fill in my password? I think the decision of Chrome developers to ignore "autocomplete="off" is kind of dumb. I hope they'll respect autocomplete="new-password" and not ignore it in a future version.


  10. <div class="form-group row margin-bottom">
         <label for="ePassword" class="col-sm-2 col-form-label">Password*</label>
          <div class="col-sm-6">
               <input type="hidden" name="EPASSWORD" id="EPASSWORD"/>
               <input autocomplete="off" CLASS="form-control" spellcheck="false" TYPE="password" name="1DC647A67DB84EE7ABA987E7662DBCF2" onchange="document.getElementById('EPASSWORD').value = this.value" />
         </div>
    </div>
    

    The name of the input text is random generated in code. How does Chrome still guesses this is the password field?

    Any way to trick Chrome to not know what field is the password field?

     

     

    chromesux.JPG


  11. I'm using TNetEncoding.URL.Encode to encode the following string:

    E+C1NU0Z0ikcOdZF158VAypoEl4nc9bTokltVV+PkfPeO3/6pmZTRo3h17SC+x6SdK4qIrNnWv3rd9RGnQ==

     

    The result is:

    E%2BC1NU0Z0ikcOdZF158VAypoEl4nc9bTokltVV%2BPkfPeO3%2F6pmZTRo3h17SC%2Bx6SdK4qIrNnWv3rd9RGnQ%3D%3D
    
    

    Trying to use TNetEncoding.URL.Decode doesn't get me back to the original string, what am I doing wrong? 

     


  12. Here are the units I use. I don't remember where I got them from, it was several years ago:

    https://drive.google.com/file/d/180sOWUiToBllr7vxgQfhb4yaidJYPQqr/view?usp=sharing

     

    To send a SNS do something like this:

     

            uses AWS.SNSService;
            
            snsService := TsnsService.Create(nil, GlobalVar.AmazonSNSKey, GlobalVar.AmazonSNSSecret);
            try
              snsService.Publish('arn:aws:sns:us-west-2:58644269878413222:_YOUR_TOPIC_', 'Your Subject', 'Your Message');
            finally
              snsService.Free;
            end;

     

    AWS-SNS.zip

    • Thanks 1
×