KaukausInsurgency / ki-dcs

Kaukasus Insurgency
5 stars 2 forks source link

Redis Integration #234

Closed Igneous01 closed 6 years ago

Igneous01 commented 6 years ago

What will go to Redis:

1) In Game Chat per server

2) Active Side Missions, Capture Points, Depots

How will we store this information in Redis:

1) Chat:ServerID:ChatID

            ie. Chat:1:1 = JSON...

2)

            SM:ServerID:SideMissionID

            CP:ServerID:CapturePointID

            Depot:ServerID:DepotID

            ie. SM:1:1                                                            - Side Mission 1 from server 1

            ie. CP:1:5                                                             - Capture Point 5 from server 1

            ie. Depot:5:9                                      - Depot 9 from server 5

What needs to change on the LUA side of things for this to work?

1)

            - Need to add code to autoincrement a chatID each time a Chat Event callback is invoked

            - Need to implement the callback for Chat Events and the necessary plumbing code to send the message out through TCP communication

            - The request would look something like { "Action":"AddOrUpdateChat", "BulkQuery":true, "Destination":"REDIS", "Data":{"RedisID1":{JSON DATA}, "RedisID2":{JSON DATA}}

            - We would need to modify the "Data" format for REDIS to inject the Redis ID to be supplied so that when we receive a bulk request we can quickly insert/update data based on the "RedisID" string

            - So for example, the request {"Action":"AddOrUpdateChat", "Data": {"1:1":{...}, "1:2":{...}, "1:3":{...} } } would be read by the TCP server and interpreted as "Chat:1:1", "Chat:1:2", "Chat:1:3", ...

            - Need to rewrite parts of TCP logic to parse the request and translate into a RedisKey as described above

            - Need to add a new enum definition for a new TCP Request 'AddOrUpdateChat'

            - Need to add a new config definition in TCP server for the 'AddOrUpdateChat' request type

            Questions left unanswered:

            1) When the game session ends / server restarts - how do we signal Redis to clear all existing chat events?

            2) How would we clear all chat events in Redis if we don't know what the last ID was?

            3) How would we notify the SignalR monitor functions that the Redis store was updated and to resend the latest data to all connected web clients?

            4) If the Redis Server goes down, and is restarted, how would the game know that it needs to resend the entire data block for all the various objects? Perhaps set Redis to write to file so that if it does crash not all data is lost

2)

            - Need to rewrite some code to add an ID property to each of the lua object classes

            - Need to add autoincrementing ID functions that auto generate an appropriate ID whenever a new Side Mission or Capture Point is added/created

            - Write the test cases for this in the UT_KI mission and scripts

            - Include the ID as part of the fields sent back to TCP Server in request

            - Rewrite parts of the TCP Server similar to the above so that it can parse the Data property and generate the Redis Key

            - Include logic that can determine if we already have sent back the Depot/Capture Point/Side Mission previously, so that we dont need to resend static data like the position and MGRS

            - Would need write new code in the TCP Server that parses the existing JSON object in the Redis Store and updates only the necessary fields that were sent back in request (THIS WILL BE HARD TO DO FLEXIBLY)

            Questions left unanswered:

            1) When the game session ends / server restarts - how do we signal Redis to clear all existing data?

            2) How would we clear all data in Redis if we don't know what the last ID was?

            3) How would we notify the SignalR monitor functions that the Redis store was updated and to resend the latest data to all connected web clients?

            4) If the Redis Server goes down, and is restarted, how would the game know that it needs to resend the entire data block for all the various objects? Perhaps set Redis to write to file so that if it does crash not all data is lost

Other related tasks:

1) We need to refactor the TCP Server methods SendToDBSingleData, SendToMySQLSingleData, SendToRedisSingleData, etc... methods as there is too much code duplication occurring - this can be solved using Generics

            ie. Create single method SendToDB<T>(input) and let the layers above figure out what type they need

2) We need to abstract this method by supplying it with a mock DBClient object so that we can put this method under unit testing to confirm the logic works as expected

3) Refactor KIDB.cs to store the ConfigReader class as a static public member which can be accessed outside. Currently we are duplicating the same config properties in both ConfigReader and KIDB which is not necessary

4) Because the KIDB is a static class with static methods, we need to be careful in how we will refactor this to be testable, as Static Classes are generally very difficult to test effectively with unit tests

Igneous01 commented 6 years ago

Completed in 872134cb63e825111bb2adcf1524ef6ebbc9730b