Forum BigDB BigDB usage on serverside without locks

Discussion and help relating to the PlayerIO database solution, BigDB.

BigDB usage on serverside without locks

Postby orcunnisli » February 22nd, 2015, 12:01 am

Hi there,

I am making an async multiplayer game and i am using BigDB only on the serverside to store/restore data between sessions. I only use BigDB methods on GameStarted() and GameClosed() methods. But I fail, even so simple they are.

Only delegate callbacks are the real problem, since i fail with them on two ways.

First one is happening when i try to use a BigDb callback to change an outer scoped variable
Code: Select all
bool isExist= false;
PlayerIO.BigDB.LoadRange("TableName", "IndexName", new object[] { IndexParam}, null, null, 10,
                    delegate(DatabaseObject[] result)
                    {
                            //Do Something
                            if(result.Length > 0)
                            {
                                 isExist= true;
                            }
                    }
);

if(isExist)
{
        //THIS FAILS SINCE DELEGATE METHOD IS POSSIBLY NOT CALLED YET
      PlayerIO.BigDB.LoadOrCreate("TableName","ObjectName"  ,
            delegate(DatabaseObject result)
            {
                 //Index mostly gives wrong value as expected
                 result.name = myArray.name;
            }
      );
}


this one can`t be solved by moving the last if(isExist) block entirely in to the delegate callback because bigDB methods can not be run inside delegates. And also my GameStarted function will be ended before BigDB delegate callback ends, so players could even interact with server before my database is loaded! Thats horrible!

Second one is happening when i try to use a BigDB method in a for loop. If i use index iterator of for in the delegate callback, index is mostly addressing wrong value because my for loop iterate before delegate callback

Code: Select all
for(int index = 0; index < myArray.Count; index ++)
{
      PlayerIO.BigDB.LoadOrCreate("TableName","ObjectName_" + index  ,
            delegate(DatabaseObject result)
            {
                 //Index mostly gives wrong value as expected
                 result.name = myArray[index].name;
            }
      );
}


So is there any easy solution to solve these situations without using complicated locks?

Is there any wait methodology for delegate callbacks?

I just want to use BigDB methods like they are synchronous.

Thanks for help!
orcunnisli
 
Posts: 7
Joined: February 4th, 2015, 8:00 pm

Re: BigDB usage on serverside without locks

Postby archipdev » February 22nd, 2015, 9:46 pm

I've started using bigDB several days ago but I think you can solve your problem by creating more functions

For your first problem, I didn't know that we can't use bigDB function inside bigDB delegate but I think you can do something like this though
Code: Select all
    bool isExist= false;
    PlayerIO.BigDB.LoadRange("TableName", "IndexName", new object[] { IndexParam}, null, null, 10,
                        delegate(DatabaseObject[] result)
                        {
                                //Do Something
                                if(result.Length > 0)
                                {
                                     otherFunction();
                                }
                        }
    );
}

   private void otherFunction()
    {
          PlayerIO.BigDB.LoadOrCreate("TableName","ObjectName"  ,
                delegate(DatabaseObject result)
                {
                     //Index mostly gives wrong value as expected
                     result.name = myArray.name;
                }
          );
    }


For your other problem, I think this should work
Code: Select all
    for(int index = 0; index < myArray.Count; index ++)
    {
         createItem(index, myArray);
    }


private void createItem(int index, string[] myArray){
PlayerIO.BigDB.LoadOrCreate("TableName","ObjectName_" + index  ,
                delegate(DatabaseObject result)
                {
                     result.name = myArray[index].name;
                      //don't forget you have to call save() at some point
                }
          );
}


archipdev
 
Posts: 28
Joined: September 6th, 2014, 10:35 am

Re: BigDB usage on serverside without locks

Postby orcunnisli » February 23rd, 2015, 2:06 am

archipdev Thanks,

I've also solved this two problems in similar ways.
For first one i used the method-inside-method (lıke the way you showed) and for second one i've used LoadKeysOrCreate instead of LoadOrCreate.

Yet my most important problem still unsolved:

"And also my GameStarted function will be ended before BigDB delegate callback ends, so players could even interact with server before my database is loaded! Thats horrible!"


How could i hold players to connect before i reload my game info from BigDB? Currently I am using a boolean (isSessionReady) that set at the very end of the last bigDB action and i reject all players from joining before this boolean set to true, but i guess this is the worst way to do this. My all BigDB actions that i called from GameStarted are async with AllowUserJoin method and I must reject even the first player that created the room with this solution (so its not a valid solution)!

At this point i need a good advice.

Thanks!
orcunnisli
 
Posts: 7
Joined: February 4th, 2015, 8:00 pm

Re: BigDB usage on serverside without locks

Postby archipdev » February 23rd, 2015, 8:51 am

I found one, not sure if it's the best

In your userJoin function :
Code: Select all
if(isSessionReady) {
   userJoinAfterGameStarted(); //a function you create
}
else {
   AddTimer(delegate {
      if(isSessionReady){
         userJoinAfterGameStarted();
         //delete timer
      }
   }, 100);
}
archipdev
 
Posts: 28
Joined: September 6th, 2014, 10:35 am

Re: BigDB usage on serverside without locks

Postby orcunnisli » February 24th, 2015, 3:04 am

archipdev thanks again!

As a similar aproach, i solved the problem with ignoring default allowUserJoin function by accepting every one in the room. All players joined the room first time are like blind spectators at this mode. Infinite players can join.

Then players could send message to to check if room information (from BigDB) is loaded. Before loading the BigDB, GotMessage reject every messages other than statusCheck, so players must send statusCheck message in periods to check if its loaded or not. After statusCheck begin returning true, players can send message joinGame. First players sended joinGame (until max player cap) could join game.

A final question: All GotMessage calls are synchronous (between each other) or not? (Do i need to lock inside GotMessage to prevent multi get/set races or deadlocks?)
orcunnisli
 
Posts: 7
Joined: February 4th, 2015, 8:00 pm

Re: BigDB usage on serverside without locks

Postby archipdev » February 24th, 2015, 9:58 am

IIRC, the gotmessage are asynchronous and you need to lock them but it's easy, I did this in my code to avoid problems

Code: Select all
Object locker;
public override void GotMessage(Joueur player, Message message)
        {
            lock (locker)
            {
                base.GotMessage(player, message);
                if (message.Type == CS.MESS_ACTION)
                {
                    gameEngine.receiveMessageOfAction(player, message);
                }
            }
        }
archipdev
 
Posts: 28
Joined: September 6th, 2014, 10:35 am


Return to BigDB



cron