During my implementation of AI process priority management recently I came across something that looks like a weird sequence of messages/events during order submission processing. These strange behaviour occurs only if the human player hits "End turn" before the AI clients have submitted their orders. I already reported that briefly
here, but now want to provide a more detailed bug report.
Important note: To test this scenario properly (AI clients which are busy doing their turns for a sufficiently long time) I modified generateOrders() in PythonAI.py to do a busy loop for 30 sec before it continues with actual order generation.
I'll try to illustrate what I found by walking through the respective log files. The first entries after hitting "End turn" are these in freeorion.log:
Code:
...
2012-07-06 15:29:01,002 DEBUG Client : MapWnd::EndTurn
2012-07-06 15:29:01,002 DEBUG Client : ClientNetworking::SendMessage() : sending message Message: TURN_ORDERS 1 --> -1(server/unknown)...
2012-07-06 15:29:01,002 DEBUG Client : (HumanClientFSM) PlayingTurn.TurnEnded
2012-07-06 15:29:01,003 DEBUG Client : (HumanClientFSM) ~PlayingTurn
2012-07-06 15:29:01,003 DEBUG Client : (HumanClientFSM) WaitingForTurnData
2012-07-06 15:29:01,003 DEBUG Client : (HumanClientFSM) WaitingForTurnDataIdle
...
So far everything is as it should be. The turn submission network message is sent to the server, the human client FSM does the transition from PlayingTurn to WaitingForTurnData state.
Now lets look at freeoriond.log to see how order submission processing proceeds server-side:
Code:
...
2012-07-06 15:29:01,003 DEBUG Server : ServerApp::HandleMessage type 16
2012-07-06 15:29:26,624 DEBUG Server : ServerApp::HandleMessage type 16
2012-07-06 15:29:26,625 DEBUG Server : ServerApp::HandleMessage type 19
2012-07-06 15:29:26,625 DEBUG Server : (ServerFSM) WaitingForSaveData.ClientSaveData
2012-07-06 15:29:26,640 DEBUG Server : ServerApp::HandleMessage type 16
2012-07-06 15:29:26,642 DEBUG Server : ServerApp::HandleMessage type 19
2012-07-06 15:29:26,642 DEBUG Server : (ServerFSM) WaitingForSaveData.ClientSaveData
2012-07-06 15:29:26,661 DEBUG Server : ServerApp::HandleMessage type 16
2012-07-06 15:29:26,664 DEBUG Server : ServerApp::HandleMessage type 19
2012-07-06 15:29:26,664 DEBUG Server : (ServerFSM) WaitingForSaveData.ClientSaveData
2012-07-06 15:29:26,664 DEBUG Server : UniverseObject::Copy Berkano has special DERELICT_SPECIAL3
2012-07-06 15:29:26,664 DEBUG Server : ... which is copied.
...
"End turn" and subsequent sending of the order submission network message was triggered at 15:29:01,002. At 15:29:01,003 ServerApp::HandleMessage reports a "type 16" message, whatever that is.
Then nothing else happens for ~25 sec! At 15:29:26,624 another "type 16" is handled, and subsequently a series of messages/events is logged that look like they belong to the save game process.
Following these messages a bunch of UniverseObject::Copy log entries like the last one quoted above appear, no need quote them in their entirety here. After these entries freeoriond.log continues with:
Code:
...
2012-07-06 15:29:26,666 DEBUG Server : GetEmpireKnownObjectsToSerialize
2012-07-06 15:29:26,666 DEBUG Server : UniverseObject::Copy has special DERELICT_SPECIAL2
2012-07-06 15:29:26,666 DEBUG Server : ... which is copied.
2012-07-06 15:29:26,666 DEBUG Server : UniverseObject::Copy has special DERELICT_SPECIAL3
2012-07-06 15:29:26,666 DEBUG Server : ... which is copied.
2012-07-06 15:29:26,666 DEBUG Server : UniverseObject::Copy has special DERELICT_SPECIAL2
2012-07-06 15:29:26,666 DEBUG Server : ... which is copied.
2012-07-06 15:29:26,667 DEBUG Server : UniverseObject::Copy has special DERELICT_SPECIAL3
2012-07-06 15:29:26,667 DEBUG Server : ... which is copied.
2012-07-06 15:29:26,667 DEBUG Server : UniverseObject::Copy has special DERELICT_SPECIAL3
2012-07-06 15:29:26,667 DEBUG Server : ... which is copied.
2012-07-06 15:29:26,673 DEBUG Server : (ServerFSM) ~WaitingForSaveData
...
At 15:29:26,673 the save game process seems to have completed. Order submission processing continues:
Code:
...
2012-07-06 15:29:26,673 DEBUG Server : (ServerFSM) WaitingForTurnEndIdle
2012-07-06 15:29:26,673 DEBUG Server : (ServerFSM) WaitingForTurnEnd.TurnOrders
2012-07-06 15:29:26,673 DEBUG Server : WaitingForTurnEnd.TurnOrders : Received orders from player 1
2012-07-06 15:29:26,673 DEBUG Server : (ServerFSM) WaitingForTurnEnd.TurnOrders
2012-07-06 15:29:26,673 DEBUG Server : WaitingForTurnEnd.TurnOrders : Received orders from player 2
2012-07-06 15:29:26,673 DEBUG Server : (ServerFSM) WaitingForTurnEnd.TurnOrders
2012-07-06 15:29:26,673 DEBUG Server : WaitingForTurnEnd.TurnOrders : Received orders from player 4
2012-07-06 15:29:26,674 DEBUG Server : (ServerFSM) WaitingForTurnEnd.TurnOrders
2012-07-06 15:29:26,674 DEBUG Server : WaitingForTurnEnd.TurnOrders : Received orders from player 3
2012-07-06 15:29:26,674 DEBUG Server : ServerApp::AllOrdersReceived()
2012-07-06 15:29:26,674 DEBUG Server : WaitingForTurnEnd.TurnOrders : All orders received.
2012-07-06 15:29:26,674 DEBUG Server : (ServerFSM) ~WaitingForTurnEndIdle
2012-07-06 15:29:26,674 DEBUG Server : (ServerFSM) ~WaitingForTurnEnd
2012-07-06 15:29:26,674 DEBUG Server : (ServerFSM) ProcessingTurn
2012-07-06 15:29:26,674 DEBUG Server : (ServerFSM) ProcessingTurnIdle
2012-07-06 15:29:26,674 ERROR Server : ServerFSM : A [ERROR: Unknown Event] event was passed to the ServerFSM. This event is illegal in the FSM's current state. It is being ignored.
2012-07-06 15:29:26,674 ERROR Server : ServerFSM : A [ERROR: Unknown Event] event was passed to the ServerFSM. This event is illegal in the FSM's current state. It is being ignored.
2012-07-06 15:29:26,674 ERROR Server : ServerFSM : A [ERROR: Unknown Event] event was passed to the ServerFSM. This event is illegal in the FSM's current state. It is being ignored.
...
At 2012-07-06 15:29:26,673 finally the server reports the reception of the turn orders from player 1 (which is the human player). That's ~25 sec after I'd hit "Turn End". The orders of the AI clients arrive effectively at the same time. As this 25 secs plus the few secs it took me to press "End turn" after turn 1 started sum up to the 30 sec busy loop i built into generateOrders(), this looks
very much like my (the human player's) turn submission message somehow "hang" until all the AI clients were finished, and then all turn submission messages where handled at once.
The next thing that's conspicuous here is the fact that ServerApp::AllOrdersReceived() is only called
once. It
should be called every time a client submits his turn orders. Every time a client submits his turn orders, the WaitingForTurnEnd.TurnOrders event handler in the server FSM is triggered. At the end of the event handler routine a WaitingForTurnEnd.CheckTurnEndConditions event is posted for further processing:
Code:
// check conditions for ending this turn
post_event(CheckTurnEndConditions());
That means we have 4 of these events waiting in the event queue of the server FSM. In this event handler (WaitingForTurnEnd.CheckTurnEndConditions) ServerApp::AllOrdersReceived() is called (to check if all clients have submitted their orders and the server FSM should transit to the next state, ProcessingTurn). However, as the log entries clearly indicate, only one of the WaitingForTurnEnd.CheckTurnEndConditions is handled properly. The other 3 events apparently only get processed
after the server FSM has made the transition into the ProcessingTurn state, so they end up handled by the unconsumed_event handler, which results in the 3 error messages at the end of the log file section quoted above. I've checked this assumption by running this test with 12 AI's, resulting in 12 of these error messages (as expected).
Now lets see what freeoriond.log tells us after that:
Code:
...
2012-07-06 15:29:26,674 DEBUG Server : ServerApp::ProcessTurns executing orders
2012-07-06 15:29:26,677 DEBUG Server : ProductionQueue::Update: Simulating future turns of production queue
2012-07-06 15:29:26,677 DEBUG Server : ProductionQueue::Update time: 0.133
2012-07-06 15:29:26,678 DEBUG Server : ========= Production Update for empire: 2 ========
...
Obviously turn processing kicks in (at 15:29:26,674) and continues from here. Lets look over to freeorion.log (client side):
Code:
...
2012-07-06 15:29:26,677 DEBUG Client : ClientNetworking::GetMessage() : received message Message: PLAYER_STATUS -1(server/unknown)...
2012-07-06 15:29:26,677 DEBUG Client : (HumanClientFSM) PlayingGame.PlayerStatus
2012-07-06 15:29:26,691 DEBUG Client : ClientNetworking::GetMessage() : received message Message: TURN_PROGRESS -1(server/unknown)...
...
I haven't omitted any log entries on the client side, so this is where freeorion.log continues. Nothing has happened here until our little chaos on the server side has cleared up, the next messages we see here are the ones to be expected to show up during server side turn processing. There's just one log entry of interest left, in freeorion.log:
Code:
...
2012-07-06 15:29:26,821 DEBUG Client : Autosaving to: /Users/.../Library/Application Support/FreeOrion/save/FreeOrion_Human_Player_Terran_0002.sav
...
Here the auto saving mechanism kicks in, as it should. Which means, it can't have interfered before. The odd thing is, if I turn off auto save, all the above doesn't happen. Turn orders arrive at the server and are handled immediately, no 25 sec wait, WaitingForTurnEnd.CheckTurnEndConditions is handled properly, no unconsumed_event errors - everything is as it should be.
Has
anyone any idea what is going on here???
I've zipped the log files and attached them to this post.