Jump to content

borni69

Members
  • Content Count

    32
  • Joined

  • Last visited

Community Reputation

0 Neutral
  1. Thanks for the Idea, and we are considering this. But we have some consideration. Our Delphi app is an API server , ISAPI webbroker module running on Apache linux docker several container instances behind a load balancer. We can share a dictionary between the threads using DataSync := TMultiReadExclusiveWriteSynchronizer.Create; We use MPM_event on apache with this setup per production server <IfDefine TSprod> ServerLimit 8 MaxRequestWorkers 200 ThreadsPerChild 25 </IfDefine> And for setup above this will give 8 dictionary per server holding almost the same information, and 25 threads will share same dictionary this will be super fast but consume more memory than memcache. We could consider reducing ServerLimit and increase ThreadsPerChild for this setup to not use so much memory per server this will increase threads using same dict. We will test a little more on this. B
  2. OK thanks all for your help, I will give it a try...
  3. Thanks, Yes you are rigth it look like Ansistring 8 bit , and it also looks like my encoding send with it is not working for memcache.. 😞 IndyTextEncoding_UTF8 tcp.Socket.Writeln(Value,IndyTextEncoding_UTF8); So I guess I Either I need to convert this delphi unicode UTF-16 string TemplateLines TemplateLines:= TFile.ReadAllText(afilepath,Tencoding.UTF8 ); to Ansistring or continue with base64encode Are there an easy way in Delphi to convert a Delphi UTF-16 string to Ansistring ? Sorry if this is a dumb question...
  4. Still have issue when storing to memcache when string is not base64 encoded this is my code Writeln to memcache tcp.IOHandler.InputBuffer.clear; command :='set '+key+' 0 0 '+length(Value).ToString+' noreply'; try tcp.Socket.Writeln(command,IndyTextEncoding_UTF8); tcp.Socket.Writeln(Value,IndyTextEncoding_UTF8); except on e: Exception do begin reportError(e.Message); exit; end; end; end; all Norwegian character like æøå ÆØÅ become ??? ??? memcache is running on Linux docker. b
  5. I guess I could change my TOML parser to also use a stream instead. procedure TtomlMalReader.scanner; var i : Integer; aline : String; LocalC : Char; begin for i := 0 to length(malLines)-1 do begin aline := malLines[i]; LineNumber:=i+1; for LocalC in aline do begin c:=localc; validateCharacter; if error > '' then begin error_line:=i+1; break; end; end; if error > '' then break; validateNewLine; end; end; As you can see I loop all lines and validate the c : char; character in each line.. So maybe I should use a TStringStream instead is that what you ment ? will also try to skip base64 and thanks again for your support. B
  6. Thanks for following up, I understand you recomandation, and we will try.. So to store it as a string we still need to do TemplateLines:=''; for I := 0 to length(FLines)-1 do begin TemplateLines:=TemplateLines+FLines[i]+sLineBreak; end; or is there better ways to do this... we will try to skip the base64
  7. We had some problem earlier with some encoding and memcache so today we store all object in memcache as base64.
  8. We see we can use SplitString to go from string to TStringDynArray  b64data := SettingTemplateClass.memcacheClass.lookup(memcached_key); TemplateLines := TNetEncoding.Base64.Decode( b64data); FLines := SplitString(TemplateLines,sLineBreak); So maybe the best way is to store the string in memcache and not the TStringDynArray all suggestion are welcome...
  9. Hi all We have a TOML template configuration system we use to hold config data. When I load a template into Delphi I use TStringDynArray to hold the data var FLines : TStringDynArray; .... FLines := TFile.ReadAllLines(afilepath,Tencoding.UTF8 ); our TOML parser also use TStringDynArray to scan the files and set the different values. after load we would like to put the data into a Memcache, so next time we don't need to load the data from disc. Is there a way to base64encode / decode TStringDynArray direct ? Today we change the data to a normal string like below.. TemplateLines:=''; for I := 0 to length(FLines)-1 do begin TemplateLines:=TemplateLines+FLines[i]+sLineBreak; end; b64data := SettingTemplateClass.encodeBase64(TemplateLines); SettingTemplateClass.memcacheClass.store( memcached_key , b64data ); So we need either to change the string back from string to TStringDynArray or base64 encode/decode TStringDynArray direct and save it to memcache ? Any suggestion recommendation.
  10. borni69

    FMX on Mac Keyboard not working

    I found it, need to run it from Delphi not just build it.. B
  11. borni69

    FMX on Mac Keyboard not working

    Hi , I am a little new on using Delphi app on OSX. But I will give it a try. I have installed x-code I have set up PAserver So now I can build a terminal app, and it works from my mac :-), so far so good . But if I create a visual FMX app called test and only add one text box to it. then I build it . On my mac I find it using my terminal and type ./test the App start but keyboard is not working... If I select edit box and type I can see the text is going into the terminal.. I guess I am doing something wrong here ? any help would be great thanks.
  12. Updated, I will try to see what changes this is making to the system.. thanks.. var acontentType : String; abase64 : String; afileName : String; FileContent : TmemoryStream; abuffer : Tbytes; begin // Pdf proxy acontentType := Request.ContentFields.Values['contenttype']; abase64 := Request.ContentFields.Values['base64']; afileName := Request.ContentFields.Values['fileName']; if ( acontentType > '') and ( abase64 > '') and ( afileName > '') then begin FileContent := TmemoryStream.Create; abuffer :=TNetEncoding.Base64.DecodeStringToBytes(abase64); FileContent.write(abuffer, length(abuffer) ); FileContent.Position := 0; // Go to the start of the stream Response.SetCustomHeader('Content-Disposition', 'attachment; filename='+ TNetEncoding.URL.Encode(afileName)); Response.ContentStream := FileContent; Response.ContentType := 'application/pdf'; Response.SendResponse; end else Response.Content:=unitGetJsonText.createJsonStatusResult ( Response , TjsonStatus.error ,'error missing content type / base64 /afileName',''); end;
  13. Hi , We have a Delphi webbroker system that receives pdf files from a web client in a base64 format. The server is just receiving them and returning them, it's like a proxy. We do this , because the PDF is created on the client site, but we can not download directly from the client, so after creation we send it to the server and back. This works perfectly for smaller pdf But when the base64 is getting bigger we are getting out of memory. The code we use are procedure TWebModule1.WebModule1pdfproxyAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var acontentType : String; abase64 : String; afileName : String; FileContent : TmemoryStream; begin // Pdf proxy acontentType := Request.ContentFields.Values['contenttype']; abase64 := Request.ContentFields.Values['base64']; afileName := Request.ContentFields.Values['fileName']; if ( acontentType > '') and ( abase64 > '') and ( afileName > '') then begin FileContent := TmemoryStream.Create; FileContent.write(TNetEncoding.Base64.DecodeStringToBytes(abase64), length(TNetEncoding.Base64.DecodeStringToBytes(abase64)) ); FileContent.Position := 0; // Go to the start of the stream Response.SetCustomHeader('Content-Disposition', 'attachment; filename='+ TNetEncoding.URL.Encode(afileName)); Response.ContentStream := FileContent; Response.ContentType := 'application/pdf'; Response.SendResponse; end else Response.Content:=unitGetJsonText.createJsonStatusResult ( Response , TjsonStatus.error ,'error missing content type / base64 /afileName',''); end; Would there be a way to store the incoming data as a file and then return it or other ideas for handle a case like this ? Thanks in advance
  14. Hi Again and thanks.. I have never used TMultiReadExclusiveWriteSynchronizer , but it looks straight forward. I created a test app and it seems to work, so I guess it is as simple as code below. except I will use a Dictionary. unit WebModuleUnit1; interface uses System.SysUtils, System.Classes, Web.HTTPApp; type TWebModule1 = class(TWebModule) procedure WebModule1DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); private { Private declarations } public { Public declarations } end; var WebModuleClass: TComponentClass = TWebModule1; Data: TStringList; DataSync: TMultiReadExclusiveWriteSynchronizer; implementation {%CLASSGROUP 'System.Classes.TPersistent'} {$R *.dfm} procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var i : Integer; begin if Request.QueryFields.Values['add'] > '' then begin // Add line DataSync.BeginWrite; try Data.Add ( Request.QueryFields.Values['add']); finally DataSync.EndWrite; end; end; Response.Content := '<html>' + '<head><title>Web Server Application</title></head>' + '<body>'; DataSync.BeginRead; try for I := 0 to data.Count-1 do begin Response.Content := Response.Content+data[i]+'</br>' end; finally DataSync.EndRead; end; Response.Content := Response.Content+' </body>' + '</html>'; end; initialization // test:='Test'; Data := TStringList.Create; DataSync := TMultiReadExclusiveWriteSynchronizer.Create; finalization Data.Clear; Data.Free; DataSync.Free; end. end. thanks
×