Recent

Author Topic: Handling concurrent access  (Read 8412 times)

Leledumbo

  • Hero Member
  • *****
  • Posts: 8319
  • Programming + Glam Metal + Tae Kwon Do = Me
Handling concurrent access
« on: December 30, 2010, 04:17:48 pm »
I'm currently writing a web service with data upload and retrieval. As a web service, it will surely be used concurrently. All provided services do database access. The problem is when the data size is quite large (when uploading big files for instance), another incoming request causes internal server error. If not big, two request incoming in almost the same time could cause that too (tried from extjs). How do I solve this?

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Handling concurrent access
« Reply #1 on: December 30, 2010, 06:02:58 pm »
Probably you need a Mutex, http://en.wikipedia.org/wiki/Mutual_exclusion

For instance, this code avoids this program to be executed twice:

Code: [Select]
program project1;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Interfaces, // this includes the LCL widgetset
  Forms, Unit1
  { you can add units after this }
  ,windows;

{$R *.res}

var
  hMutex: THandle;
begin
  hMutex := CreateMutex(nil, True, PChar('MyUniqueName'));
  if (hMutex <> 0) and (GetLastError = 0) then
  begin
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
    Application.Run;
  end;
end.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8319
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Handling concurrent access
« Reply #2 on: December 31, 2010, 05:39:02 am »
Well, what should I say to the currently waiting request then? Reject with "database is busy" or what? I wonder how PHP handles this.

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Handling concurrent access
« Reply #3 on: December 31, 2010, 11:07:42 am »
You could wait on a loop until a timeout and use a message like "Timeout reached ".

Someting like:

Code: [Select]
  TimeOut := GetTickCount + 10000;
  repeat
    hMutex := CreateMutex(nil, True, PChar('MyUniqueName2'));
    Application.ProcessMessages;
  until ((hMutex <> 0) and (GetLastError = 0)) or (GetTickCount > TimeOut);
  if (hMutex <> 0) and (GetLastError = 0) then
  begin
    try 
      //
      // your code
      //
    finally
      ReleaseMutex(hMutex);
    end;
  end
  else
    ShowMessage('Timeout reached');
« Last Edit: December 31, 2010, 11:22:47 am by typo »

Leledumbo

  • Hero Member
  • *****
  • Posts: 8319
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Handling concurrent access
« Reply #4 on: December 31, 2010, 11:48:15 am »
Thanks, but without asking, I know that it's Windows only. The deployment platform is a Linux box. Perhaps I need a critical section?

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Handling concurrent access
« Reply #5 on: December 31, 2010, 12:15:38 pm »
I don't know if there is any implementation of Mutexes for Linux in Lazarus.

AFAIK, Linux Mutexes can't be used to different processes, maybe you need a Semaphore, more specifically a Binary Semaphore.
« Last Edit: December 31, 2010, 04:07:40 pm by typo »

McCorder

  • New Member
  • *
  • Posts: 10
Re: Handling concurrent access
« Reply #6 on: January 03, 2011, 06:53:05 pm »
Probably a silly comment, but for web services shouldn't you pass off each request onto a separate thread allowing more than one to run concurrently ? You could limit the numbers of threads by having a pool of available ones for use.

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Handling concurrent access
« Reply #7 on: January 03, 2011, 07:05:05 pm »
Mutexes allow different threads or processes to share resources that should be accessed by one at a time.
« Last Edit: January 03, 2011, 07:26:38 pm by typo »

Leledumbo

  • Hero Member
  • *****
  • Posts: 8319
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Handling concurrent access
« Reply #8 on: January 04, 2011, 03:36:45 pm »
Quote
Probably a silly comment, but for web services shouldn't you pass off each request onto a separate thread allowing more than one to run concurrently ? You could limit the numbers of threads by having a pool of available ones for use.
With one database server, that wouldn't make any difference.

Either mutex or semaphore, I don't really care. It's just something that can block for a while when another operation is using the database.

Update: I've got an idea to use empty temp file to indicate whether a process is using the database or not and wait until that file gets deleted.

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Handling concurrent access
« Reply #9 on: January 04, 2011, 03:48:50 pm »
Except for the fact that file creation and deletion can have their own errors, mutexes or binary semaphores have the same effect.

McCorder

  • New Member
  • *
  • Posts: 10
Re: Handling concurrent access
« Reply #10 on: January 09, 2011, 12:47:03 am »
Quote
Probably a silly comment, but for web services shouldn't you pass off each request onto a separate thread allowing more than one to run concurrently ? You could limit the numbers of threads by having a pool of available ones for use.
With one database server, that wouldn't make any difference.

Either mutex or semaphore, I don't really care. It's just something that can block for a while when another operation is using the database.

Update: I've got an idea to use empty temp file to indicate whether a process is using the database or not and wait until that file gets deleted.

The database server (if it is a server) will be able to handle multiple connections. So you have a pool of them (say 10) which you pass off to a new thread in response to a new request. If you need to block then your server is not a server really, it can only handle one request.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8319
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Handling concurrent access
« Reply #11 on: January 09, 2011, 03:58:11 am »
Quote
The database server (if it is a server) will be able to handle multiple connections. So you have a pool of them (say 10) which you pass off to a new thread in response to a new request. If you need to block then your server is not a server really, it can only handle one request.
Yeah, probably the client library isn't compiled with thread safe option enabled.

 

TinyPortal © 2005-2018