void force_reconnect(jsonrpc_server_t* server) { INFO("Reconnecting to server %.*s:%d for conn %.*s.\n", STR(server->addr), server->port, STR(server->conn)); force_disconnect(server); bev_connect(server); }
void wait_server_backoff(unsigned int timeout /* seconds */, jsonrpc_server_t* server, bool delay) { if(!server) { ERR("Trying to close/reconnect a NULL server\n"); return; } if(delay == false) { if (requests_using_server(server) <= 0) { if(server->status == JSONRPC_SERVER_RECONNECTING) { bev_connect(server); } else if(server->status == JSONRPC_SERVER_CLOSING) { close_server(server); } return; } } const struct timeval tv = {timeout, 0}; server_backoff_args_t* args = pkg_malloc(sizeof(server_backoff_args_t)); CHECK_MALLOC_VOID(args); memset(args, 0, sizeof(server_backoff_args_t)); args->ev = evtimer_new(global_ev_base, server_backoff_cb, (void*)args); CHECK_MALLOC_GOTO(args->ev, error); args->server = server; args->timeout = timeout; if(evtimer_add(args->ev, &tv)<0) { ERR("event_add failed while setting request timer (%s).", strerror(errno)); goto error; } return; error: ERR("schedule_server failed.\n"); if(args) { if(args->ev) { evtimer_del(args->ev); } pkg_free(args); } if (server->status == JSONRPC_SERVER_CLOSING) { ERR("Closing server now...\n"); close_server(server); } else if (server->status == JSONRPC_SERVER_RECONNECTING) { ERR("Reconnecting server now...\n"); force_reconnect(server); } }
void connect_servers(jsonrpc_server_group_t** group) { INIT_SERVER_LOOP FOREACH_SERVER_IN(group) server = wgroup->server; if(server->status != JSONRPC_SERVER_FAILURE && server->status != JSONRPC_SERVER_RECONNECTING) { bev_connect(server); } ENDFOR }
void cmd_pipe_cb(int fd, short event, void *arg) { struct jsonrpc_pipe_cmd *cmd; if (read(fd, &cmd, sizeof(cmd)) != sizeof(cmd)) { ERR("FATAL ERROR: failed to read from command pipe: %s\n", strerror(errno)); return; } switch(cmd->type) { case CMD_CLOSE: if(cmd->server) { wait_close(cmd->server); } goto end; break; case CMD_RECONNECT: if(cmd->server) { wait_reconnect(cmd->server); } goto end; break; case CMD_CONNECT: if(cmd->server) { bev_connect(cmd->server); } goto end; break; case CMD_UPDATE_SERVER_GROUP: if(cmd->new_grp) { jsonrpc_server_group_t* old_grp = *global_server_group; *global_server_group = cmd->new_grp; free_server_group(&old_grp); } lock_release(jsonrpc_server_group_lock); goto end; break; case CMD_SEND: break; default: ERR("Unrecognized pipe command: %d\n", cmd->type); goto end; break; } /* command is SEND */ jsonrpc_req_cmd_t* req_cmd = cmd->req_cmd; if(req_cmd == NULL) { ERR("req_cmd is NULL. Invalid send command\n"); goto end; } jsonrpc_request_t* req = NULL; req = create_request(req_cmd); if (!req || !req->payload) { json_t* error = internal_error(JRPC_ERR_REQ_BUILD, NULL); pv_value_t val; char* freeme = NULL; jsontoval(&val, &freeme, error); if(req_cmd->route.len <=0 && send_to_script(&val, req_cmd)<0) { ERR("Failed to build request (method: %.*s, params: %.*s)\n", STR(req_cmd->method), STR(req_cmd->params)); } if(freeme) free(freeme); if(error) json_decref(error); free_req_cmd(req_cmd); goto end; } int sent = jsonrpc_send(req_cmd->conn, req, req_cmd->notify_only); char* type; if (sent<0) { if (req_cmd->notify_only == false) { type = "Request"; } else { type = "Notification"; } WARN("%s could not be sent to connection group: %.*s\n", type, STR(req_cmd->conn)); fail_request(JRPC_ERR_SEND, req, "Failed to send request"); } end: free_pipe_cmd(cmd); }