You are not logged in.
Pages: 1
I'm developing a simple game server with a server side part written in mORMot that serve and shuffle cards, and front end written in SmartMS.
Delphi mORMot PORN game
http://youtu.be/Jn6ODHkg6js
a) The game will require authentication; OK
b) the cards need to be shuffled, mormot should shuffle and deal hands; OK
c) on GameOver I need to "send scores" from SmartMS to my server and then immediately "show highscores TOP 5".
But something goes wrong here but I can't find out what.
When a player finishes a game just submit POST some data, the score to DB (NewRec) and then immediately I call another service to show highscores TOP 5 (GetRec). If the score is within a certain range at the top 5 and replay the game.
POST http://127.0.0.1:8080/root/Jogo.NewRec? … 9072891137
RESPONSE IS: 200
{"result":[56]}
POST http://127.0.0.1:8080/root/Jogo.GetRec? … 904733ef11
RESPONSE IS: 500
{
"errorCode":500,
"error":
{"ESQLite3Exception":{
"ClassName":"ESQLite3Exception",
"Address":"02EFFA7C",
"ErrorCode": 5,
"SQLite3ErrorCode": "BUSY",
"Message": "Error SQLITE_BUSY (5) using 3.8.7.4 - \"database is locked\" extended_errcode=5"
}}
}
Any idea?
Last edited by warleyalex (2015-03-25 03:26:57)
Offline
I think SQLite is supposed to be used for concurrent access using interface based services writing/reading in sequence. For me anyway, this is not working as expected. I suspect that some another process (NewRec?) has a lock on a database. Maybe Props := TSQLDBSQLite3ConnectionProperties.Create(StringToUTF8('BasededadosSQLite.db3'),'','','');
I cannot reproduce the issue. f.i. In SmartMS, if i click in a button that fires NewRec/GetRec methods in sequence, server will throwing the 500 internal error. After some time (a basic DDOS attack), overthrow the server, server will crash.
// NewRec is an interface based service that adds "Name", "Moves" and "Time" to database.
TServiceJogo.Create(Client).NewRec(20,20,
lambda (res: integer)
Result := res;
end,
lambda
WriteLn('Error calling the method!');
end);
// GetRec is an interface based service that return TOP 5,
SQL = 'SELECT Nome, Moves, Tempo FROM Game ORDER BY Moves,Tempo ASC LIMIT 5
TServiceJogo.Create(Client).GetRec(
lambda (res: variant)
WriteLn(res);
end,
lambda
WriteLn('Error calling the method!');
end);
Offline
How do you use the DB?
Are you using an external SQLite3 database?
The whole SynSQLite3.pas access is protected by a critical section, so is thread safe, even when accessed from an external SQLite3 database.
So I do not know what it wrong in your case.
BTW why are you using raw SQL, and not the ORM?
Offline
Thank you.
I'm just drunk enough to tell you that I'm re-using the same exact Sqlite3 file "BasededadosSQLite.db3" from both internal as well as external. Exactly, I have defined my server model, and DB and I use ORM to NewRec method.
TSQLRestServerDB.Create(Model, 'BasededadosSQLite.db3',true) // method NewRec
Believe it or not, my "GetRec method" access sqlite as external database
TSQLDBSQLite3ConnectionProperties.Create('BasededadosSQLite.db3', '', '', '')
I think I can not switch from internal to external the way I'm doing to write and read sequencially. I suspect that some another process (NewRec?) will lock on a database in some moment. That way, my server overflows. I particularly like the end of the story, my mORMot server just went down.
Offline
The 'BasededadosSQLite.db3' DB is accessed twice!
Once from TSQLRestServerDB, and another time as external DB.
This is why it does not work.
You should just set a void in-memory DB for TSQLRestServerDB, then register all tables as external.
Offline
Pages: 1