Comments (7)
Hello friend,
Can you send a small project to test it? I'm using Brook fine with multi-threads, but with FastCGI broker. I can test it with embedded server too.
CurrentAction is a useful property used only for non-thread apps. It isn't used internally in Brook.
And what is your operating system?
If this is a bug, I'll fix it ASAP. 👍
from brookframework.
Oh, I forgot to mention -- I used a long delay (~10 sec) in TAction.Get()
handler to simulate busy activity. Specially crafted for-loop doing nothing 1 billion times will be ok )). To be sure there are two simultaneous requests I used different browsers for connecting - Opera sometimes cheats and do single request for two different tabs if url is the same.
Source is actually identical to brookframework\demos\simple\helloworld\embeddedserver
from master branch, the only modifications are .Threaded := true;
and delay.
IDE is Lazarus-1.1-42083-fpc-2.7.1-20130714-win32.
from brookframework.
Thank you. I'm working on it right now.
from brookframework.
I forgot to ask. Do you have any idea how to implement this? I'm trying, but it seems a bit complex.
from brookframework.
Fixed (0b45081).
Configure your broker to:
unit Brokers;
(...)
function App: TCustomHTTPApplication;
begin
Result := BrookApp.Instance as TCustomHTTPApplication;
end;
initialization
App.Port := 1024; // or your port
App.Threaded := True;
(...)
I tested it with:
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
BrookAction, sysutils;
type
{ TMyAction1 }
TMyAction1 = class(TBrookAction)
public
procedure Get; override;
end;
{ TMyAction2 }
TMyAction2 = class(TBrookAction)
public
procedure Get; override;
end;
implementation
{ TMyAction1 }
procedure TMyAction1.Get;
begin
Write('Action 1: %s', [FormatDateTime('dd/mm/yyyy hh:nn:ss', Now)]);
Sleep(1000 * 10); // 10 sec delay
end;
{ TMyAction2 }
procedure TMyAction2.Get;
begin
Write('Action 2: %s', [FormatDateTime('dd/mm/yyyy hh:nn:ss', Now)]);
end;
initialization
TMyAction1.Register('/action1');
TMyAction2.Register('/action2');
end.
Calling fine http://localhost:1024/action1
and http://localhost:1024/action2
simultaneous.
Please test and close this issue if work fine for you! :)
from brookframework.
Your fix works under Win32, but not under Linux. Some peculiarities of threads implementation under linux not allow terminating of thread -- it continue running even when Action processing is complete. I am not sure which thread remain running, connection or router. Maybe VThread.WaitFor
hangs up - I can't figure out yet.
Anyway, I think creating one more thread specially for router is too much. Separate thread is already created for each connection, so we doesn't want one more thread for router inside this connection - it is just waste of resources. In my case resources are precious - I develop application which would run under embedded linux, with no HDD and minimal memory.
All we need is to create separate instance of TBrookRouter
in each thread. Now TBrookRouter.Service()
return singleton, so I solved this problem another way - I create separate instance not of TBrookRouter
, but of TAction
.
Please see my patch.
--- brookrouter0.pas Tue Jul 16 08:12:36 2013
+++ brookrouter.pas Tue Jul 16 08:37:35 2013
@@ -89,14 +89,14 @@
{ Provides features for the route handling. }
TBrookRouter = class(TBrookObject)
private
- FCurrentAction: TBrookAction;
- FCurrentRoute: TBrookRoute;
+ //FCurrentAction: TBrookAction;
+ //FCurrentRoute: TBrookRoute;
FRoutes: TBrookRoutes;
protected
function CreateRoutes: TBrookRoutes; virtual;
- procedure DoCreateAction(out AActionClass: TBrookActionClass); virtual;
- procedure DoFreeAction; virtual;
- procedure DoExecuteAction(ARequest: TRequest; AResponse: TResponse;
+ function DoCreateAction(out AActionClass: TBrookActionClass):TBrookAction; virtual;
+ procedure DoFreeAction(AAction:TBrookAction); virtual;
+ procedure DoExecuteAction(AAction:TBrookAction; ARequest: TRequest; AResponse: TResponse;
ANames, AValues: TBrookArrayOfString); virtual;
public
{ Creates an instance of a @link(TBrookRouter) class. }
@@ -150,9 +150,9 @@
{ List of available routes. }
property Routes: TBrookRoutes read FRoutes write FRoutes;
{ The current action. }
- property CurrentAction: TBrookAction read FCurrentAction;
+ //property CurrentAction: TBrookAction read FCurrentAction;
{ The current route. }
- property CurrentRoute: TBrookRoute read FCurrentRoute;
+ //property CurrentRoute: TBrookRoute read FCurrentRoute;
end;
implementation
@@ -311,24 +311,23 @@
Result := TBrookRoutes.Create;
end;
-procedure TBrookRouter.DoCreateAction(out AActionClass: TBrookActionClass);
+function TBrookRouter.DoCreateAction(out AActionClass: TBrookActionClass):TBrookAction;
begin
- FreeAndNil(FCurrentAction);
- FCurrentAction := AActionClass.Create;
+ Result := AActionClass.Create;
end;
-procedure TBrookRouter.DoFreeAction;
+procedure TBrookRouter.DoFreeAction(AAction:TBrookAction);
begin
- FreeAndNil(FCurrentAction);
+ AAction.Free;
end;
-procedure TBrookRouter.DoExecuteAction(ARequest: TRequest; AResponse: TResponse;
+procedure TBrookRouter.DoExecuteAction(AAction:TBrookAction; ARequest: TRequest; AResponse: TResponse;
ANames, AValues: TBrookArrayOfString);
begin
- FCurrentAction.FillFields(ARequest);
- FCurrentAction.FillParams(ARequest);
- FCurrentAction.FillValues(ANames, AValues);
- FCurrentAction.DoRequest(ARequest, AResponse);
+ AAction.FillFields(ARequest);
+ AAction.FillParams(ARequest);
+ AAction.FillValues(ANames, AValues);
+ AAction.DoRequest(ARequest, AResponse);
end;
class procedure TBrookRouter.RegisterService;
@@ -563,6 +562,7 @@
VActClass: TBrookActionClass = nil;
VDefaultActClass: TBrookActionClass = nil;
VRedirect, VMatchMethod, VMatchPattern: Boolean;
+ AAction:TBrookAction;
begin
C := FRoutes.List.Count;
if C = 0 then
@@ -585,7 +585,7 @@
Continue;
VMatchMethod := True;
VActClass := PRoute^.ActionClass;
- FCurrentRoute := PRoute^;
+ //FCurrentRoute := PRoute^;
if PRoute^.Method <> rmAll then
Break;
end;
@@ -615,7 +615,7 @@
if VRedirect and Canonicalize(ARequest, AResponse) then
Exit;
VActClass := PRoute^.ActionClass;
- FCurrentRoute := PRoute^;
+ //FCurrentRoute := PRoute^;
Break;
end;
if not Assigned(VActClass) then
@@ -625,10 +625,10 @@
raise EBrookHTTP404.Create(BROOK_HTTP_REASON_PHRASE_NOT_FOUND);
end;
try
- DoCreateAction(VActClass);
- DoExecuteAction(ARequest, AResponse, VNames, VValues);
+ AAction := DoCreateAction(VActClass);
+ DoExecuteAction(AAction, ARequest, AResponse, VNames, VValues);
finally
- DoFreeAction;
+ DoFreeAction(AAction);
end;
end;
It works without applying 0b45081
both on Windows and Linux.
The only thing I am not sure if make TAction as local variable is enough, or maybe TBrookRouter should be also made as local instance inside connection thread.
from brookframework.
Your patch is perfect and fixes the bug! I made few changes before applying it (251d319).
Please send your name to be added in CONTRIBUTORS file (https://github.com/silvioprog/brookframework/blob/master/CONTRIBUTORS.txt).
Thank you very much again and good luck in your project with Brook friend. After, if you follow, we will add it in success cases with Brook! 👍
from brookframework.
Related Issues (20)
- Why plugins projects on github to brookframework is closing? HOT 4
- Telegram plugin for brookframework HOT 15
- i18n HOT 4
- Version 4 ? HOT 14
- libbrook.pas in Source HOT 3
- tardigrade demos throwing errors in libbrook HOT 4
- Server requirements? HOT 4
- dopf & LastInsertID HOT 4
- httprouter.lpr throwing error HOT 2
- How am I supposed to free worker thread in brook daemon? HOT 9
- Use legacy application with tardigrade HOT 19
- CPU Activity is high for tardigrade projects BROOK4 HOT 4
- More documentation HOT 1
- Can't get POST request data HOT 13
- Brookframework with sagui (legacy) HOT 11
- HTTP Client HOT 1
- Where did the captcha plugin for 4.0 go? HOT 1
- Some suggestion about JTemplate? HOT 3
- [IDEA] New repository HOT 1
- EBrookHTTPServer: Failed to send data in request for HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from brookframework.