36. Server management part 5: Runtime configuration

iFun Engine allows changing some server features while the server is running.

36.1. Configurable flags during runtime

Configurable functions are the iFun Engine flags mentioned below and flags defined directly by server programmers. (For more on adding flags, please see Programming part 3: Program execution parameters.)

Important

These functions are not changed in MANIFEST.json. When flag values are changed, the server only keeps the changed values as long as it is running, and all are reset when it restarts.

36.1.1. iFun Engine flags

Logging functions:

  • minloglevel: Change the minimum log level output.
  • v: Output a verbose log.
  • alsologtostderr: Output a log file and a log on the console as well.
  • session_message_logging_level: Change the session message log level between client and server. If 0, logs are not left; if 1, only message type and length are logged; if 2, all messages are dumped. For more details, please see Networking parameters.
  • rpc_message_logging_level: Change the message log level for RPC communication between servers. If 0, logs are not left; if 1, only message type and length are logged; if 2, all messages are dumped. For more details, please see Distribution parameters.

Server performance functions:

  • enable_event_profiler: Enable iFun Engine’s event profiling feature. For more details, please see Event profiling: details.
  • event_threads_size: Set the number of event threads. Event threads are iFun Engine’s main threads. For more details, please see Event parameters.

Client control functions:

  • client_current_version: Change the latest client version allowed by servers. Clients without this version are denied access. For more details, please see Client version control.

36.1.2. Flags added by server programmers

As explained in Programming part 3: Program execution parameters, after flags are added to the server, those flags must be set as flags that can be modified during runtime in MANIFEST.json.

...
"RuntimeConfiguration": {
  "enable_runtime_configuration": true,
  "additional_configurations": ["flag1", "flag2", ... ]
}
...

For instance, you could set a Google flag as follows for whether or not a gold-giving event is in progress upon login.

DEFINE_bool(enable_gold_event,   // flag 의 이름을 입력합니다.
            false,               // flag 의 기본값을 입력합니다.
            "gold event flag");  // flag 의 설명을 입력합니다.

Set flags defined this way to be modifiable during runtime in MANIFEST.json as follows.

...
"RuntimeConfiguration": {
  "enable_runtime_configuration": true,
  "additional_configurations": ["enable_gold_event"]
}
...

36.2. Enabling runtime configuration changes

In the RuntimeConfiguration section in MANIFEST.json, set enable_runtime_configuration to true.

...
"RuntimeConfiguration": {
  "enable_runtime_configuration": true,
  "additional_configurations": []
}
...

Important

RuntimeConfiguration works based on ApiService and ApiService must be enabled, as explained in ApiService parameters.

36.3. RESTful APIs to change runtime configuration

36.3.1. Searching for all configurable flags

GET /v1/configurations/

Sample request:

GET /v1/configurations/ HTTP/1.1

Sample response:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "minloglevel": {
    "type": "int32",
    "desc": "Messages logged at a lower level than this don't actually get logged anywhere",
    "value": "0"
  },
  ...
}

36.3.2. Searching for particular flags

GET /v1/configurations/<flag_name>
Parameters:
  • flag_name – Name of flag to search.

Example 1: If a flag exists:

Request:

GET /v1/configurations/minloglevel HTTP/1.1

Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "minloglevel": {
    "type": "int32",
    "desc": "Messages logged at a lower level than this don't actually get logged anywhere",
    "value": "0"
  }
}

Example 2: If a flag does not exist:

Request:

GET /v1/configurations/no_flag HTTP/1.1

Response:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
    "no_flag": {
        "message": "This is not available",
        "available_configurations": {
            "minloglevel": {
                "type": "int32",
                "desc": "Messages logged at a lower level than this don't actually get logged anywhere"
            },
            ...
        }
    }
}

36.3.3. Changing particular flag values

PUT /v1/configurations/<flag_name>/<value>
Parameters:
  • flag_name – Name of the flag to change.
  • value – Value to change.

Example 1: If the value is valid:

Request:

PUT /v1/configurations/minloglevel/1 HTTP/1.1

Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "minloglevel": {
    "result": "minloglevel set to 1\n"
  }
}

Example 2: If the value is invalid:

Request:

PUT /v1/configurations/minloglevel/one HTTP/1.1

Response:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "minloglevel": {
    "result": "The 'one' is not a valid value"
  }
}

36.3.4. Restricting client version

36.3.4.1. Searching for compatible client version data

If the following API is invoked, you can import the client_compatible_versions set in the AppInfo component in MANIFEST.json.

GET /v1/configurations/compatible_client_versions

Example:

Request:

GET /v1/configurations/compatible_client_versions HTTP/1.1

Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "current_compatible_versions": ["0.0.1","0.0.2"]
}

36.3.4.2. Changing compatible client version data

You can change the compatible client version by invoking the following API.

POST /v1/configurations/compatible_client_versions

Example:

Request:

POST /v1/configurations/compatible_client_versions HTTP/1.1

["0.0.3", "0.0.4"]

Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "current_compatible_versions": ["0.0.3", "0.0.4"]
}

Important

AppInfo data is not changed in MANIFEST.json. When the server restarts, all changes are reverted.

36.4. Runtime configuration flag guide

iFun Engine’s runtime configuration changes work by changing Gflag values. Therefore, gflag must be invoked directly in the code used by the flags that can be reconfigured.

In the example below there is a bug because values are saved in global variables and used instead of read directly even though enable_glod_event was set as a runtime configurable flag as explained in Make custom flags dynamically configurable.

Example of incorrect use:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
DEFINE_bool(enable_gold_event, false, "gold event flag");

bool the_is_gold_event_enabled = false;

void EventManager::Initialize() {
  the_is_gold_event_enabled = FLAGS_enable_gold_event;
}

bool EventManager::IsGoldEventEnabled() {
  return the_is_gold_event_enabled;
}


void OnLogin() {
  Ptr<User> user = User::Fetch(...);

  if (EventManager::IsGoldEventEnabled()) {
    user->SetGold(user->GetGold() + 100);
  }
}

The example above must be modified as follows.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
DEFINE_bool(enable_gold_event, false, "gold event flag");

bool EventManager::IsGoldEventEnabled() {
  return FLAGS_enable_gold_event;
}

void OnLogin() {
  Ptr<User> user = User::Fetch(...);

  if (EventManager::IsGoldEventEnabled()) {
    user->SetGold(user->GetGold() + 100);
  }
}