NAME
‘on_issue’ - event which gets invoked when connection statistics fall outside the designated range.
SYNOPSIS
#include <game-carrier/server.h>
GC_ADAPTER_EVENT
GCT_INT on_issue(
GCT_INTPTR conn_user,
GCT_INT id,
GCT_COUNTER_VALUE value);
Parameters:
conn_user
GCT_INTPTR
User data associated with the connection.id
GCT_INT
Stores the statistic id.value
GCT_COUNTER_VALUE
Identifies the current value of the statistic.
RETURN VALUE
The on_issue
function can return a value from the gc_stat_reaction
enum,
indicating how to handle a connection issue.
The available options are:
GC_STAT_REACTION_DEFAULT
(0) - perform the default handling.GC_STAT_REACTION_CLOSE
(1) - close the connection.GC_STAT_REACTION_IGNORE
(2) - ignore the connection issue.
DESCRIPTION
The on_issue
function is triggered by the gcs
when connection statistics
fall outside the designated range.
The on_issue
event is executed within the gcs
worker thread context, and
as connection events are serialized, synchronization primitives are unnecessary.
The connection is not tied to a specific thread in the worker thread pool, so
different threads may handle connection events.
The conn_user
parameter holds user data associated with the connection,
which was returned by the on_connect
call.
The id
parameter represents the statistic ID, and it corresponds to an
element from the gc_conn_stats
enum. Possible values for id
are:
GC_CONN_STAT_MSG_PER_SECOND
(1) - Number of messages per second. Corresponds to themsg_per_second
parameter in the configuration file.GC_CONN_STAT_BYTES_PER_SECOND
(2) - Number of received bytes per second. Corresponds to thekbytes_per_second
parameter in the configuration file.GC_CONN_STAT_MAX_MSG_SIZE
(3) - Maximum message size. Corresponds to themax_msg_size
parameter in the configuration file.GC_CONN_STAT_OUTPUT_QUEUE_SIZE
(4) - Output message queue size. Corresponds to theoutput_queue_size
parameter in the configuration file.
The value
parameter indicates the current value of the specific statistic.
Each statistic has two alarm levels: YELLOW and RED. If a statistic
falls into the RED zone, the default action, typically connection closure,
is triggered unconditionally. If it enters the YELLOW zone, the on_issue
event is invoked. The application can determine the appropriate action for the
connection in such cases by providing a return value.
Limit values for statistics can be configured either through a configuration
file or via API calls. The conn_critical
section sets the RED zone limits,
while the conn_notice
section sets the YELLOW zone limits. These sections
are placed in the root section of the configuration file. Additionally, specific
applications can override default settings by placing them in the application
configuration section. Moreover, the application has the ability to override
default settings using the connectionSetLimit
API call.
EXAMPLE
#include <game-carrier/server.h>
#include <stdlib.h>
/*
In the following example the application ignores the `max_msg_size` issue
* for the first message. And closes the connection for the other messages.
*/
struct core_api gc_api;
struct connection_data {
GCT_INTPTR handle;
int message_count;
/* user data asociated with connection */
};
GC_ADAPTER_EVENT
int adapter_initialize(int id, struct core_api *api, const void *load_path)
{
gc_api = *api;
return 0;
}
GC_ADAPTER_EVENT
GCT_INTPTR on_connect(
GCT_INT app_id,
GCT_INTPTR handle,
GCT_INT pid,
GCT_CSTR rip,
GCT_INT rport,
GCT_CSTR lip,
GCT_INT lport,
GCT_CSTR udata)
{
/* Allocate user data */
struct connection_data * conn = malloc(sizeof(struct connection_data));
/* Out of memory, failed */
if (conn == NULL) {
return GC_DROP_CONNECTION;
}
/* Save connection hadnle */
conn->handle = handle;
/* Initialize message counter */
conn->message_count = 0;
/* Set limit for a connection */
GCT_COUNTER_VALUE one_mb = 1024 * 1024;
gc_api.connectionSetLimit(handle, GC_STAT_STATUS_YELLOW, GC_CONN_STAT_MAX_MSG_SIZE, one_mb);
/* Initialize other fields ......... */
/* Return a pointer to our data as user_data */
return (GCT_INTPTR)conn;
}
GC_ADAPTER_EVENT
void on_message(
GCT_INTPTR user,
GCT_PTR data,
GCT_SIZE len)
{
struct connection_data * conn = (struct connection_data *)user;
/* Increase message counter for a connection */
++conn->message_count;
/* Continue processing message... */
}
GC_ADAPTER_EVENT
GCT_INT on_issue(
GCT_INTPTR user,
GCT_INT id,
GCT_COUNTER_VALUE value)
{
struct connection_data * conn = (struct connection_data *)user;
if (id != GC_CONN_STAT_MAX_MSG_SIZE) {
/* Ignore everything is not related to max_msg_size */
return GC_STAT_REACTION_DEFAULT;
}
/* Check message_count to choose a behaviour */
/* Note that on_message is not called yet! */
if (conn->message_count <= 0) {
/* The counter is zero, this is a first message, ignore */
return GC_STAT_REACTION_IGNORE;
} else {
/* The counter is non-zero, this is not a first message, close */
return GC_STAT_REACTION_CLOSE;
}
}
SEE ALSO
connectionSetLimit
, on_connect
, on_disconnect
, on_message
, gc_conn_stats
, gc_stat_reaction