void QmfObject::method_call_async(std::string method, qpid::types::Variant::Map in_args, void *user_data, uint32_t timeout_ms) { uint32_t correlation_id; QmfAsyncRequest *ar; assert(_method_response_fn); ar = new QmfAsyncRequest(); ar->method = method; ar->obj = this; ar->user_data = user_data; ar->timeout = timeout_ms; ar->args = in_args; if (_connected) { qb_loop_timer_handle th; _qa->call_method_async(ar, &_qmf_data); g_timer_stop(ar->time_queued); g_timer_start(ar->time_execed); ar->state = QmfAsyncRequest::JOB_RUNNING; ar->ref(); qb_loop_timer_add(NULL, QB_LOOP_MED, timeout_ms * QB_TIME_NS_IN_MSEC, ar, method_call_tmo, &th); } else { ar->state = QmfAsyncRequest::JOB_SCHEDULED; g_timer_start(ar->time_queued); _pending_jobs.push_back(ar); } }
void QmfObject::run_pending_calls(void) { Agent a = _qmf_data.getAgent(); for (list<QmfAsyncRequest*>::iterator it = _pending_jobs.begin(); it != _pending_jobs.end(); ++it) { QmfAsyncRequest* ar = *it; qb_loop_timer_handle th; uint32_t correlation_id = a.callMethodAsync(ar->method, ar->args, _qmf_data.getAddr()); _outstanding_calls[correlation_id] = ar; g_timer_stop(ar->time_queued); g_timer_start(ar->time_execed); ar->state = QmfAsyncRequest::JOB_RUNNING; ar->ref(); mainloop_timer_add(ar->timeout, ar, method_call_tmo, &th); } }
static void method_call_tmo(void* data) { QmfAsyncRequest *ar = (QmfAsyncRequest *)data; gdouble elapsed = 0; if (ar->state == QmfAsyncRequest::JOB_COMPLETED) { // all good - it's finished } else { // timed out :( qpid::types::Variant::Map empty_args; if (ar->state == QmfAsyncRequest::JOB_SCHEDULED) { ar->obj->method_response(ar, empty_args, QmfObject::RPC_NOT_CONNECTED); } else { ar->obj->method_response(ar, empty_args, QmfObject::RPC_TIMEOUT); } } ar->unref(); }
void QmfObject::run_pending_calls(void) { qb_loop_timer_handle th; QmfAsyncRequest* ar; Agent a = _qmf_data.getAgent(); for (list<QmfAsyncRequest*>::iterator it = _pending_jobs.begin(); it != _pending_jobs.end(); ++it) { ar = *it; _qa->call_method_async(ar, &_qmf_data); g_timer_stop(ar->time_queued); g_timer_start(ar->time_execed); ar->state = QmfAsyncRequest::JOB_RUNNING; ar->ref(); qb_loop_timer_add(NULL, QB_LOOP_MED, ar->timeout * QB_TIME_NS_IN_MSEC, ar, method_call_tmo, &th); } }
bool QmfObject::process_event(ConsoleEvent &event) { QmfAsyncRequest *ar; if (event.getType() == CONSOLE_METHOD_RESPONSE) { ar = _outstanding_calls[event.getCorrelator()]; if (ar) { qpid::types::Variant::Map my_map = event.getArguments(); if (ar->state == QmfAsyncRequest::JOB_RUNNING) { method_response(ar, my_map, RPC_OK); } else { qb_log(LOG_ERR, " method_response is too late! "); } _outstanding_calls.erase(event.getCorrelator()); ar->unref(); } } else if (event.getType() == CONSOLE_EXCEPTION) { ar = _outstanding_calls[event.getCorrelator()]; if (ar) { qpid::types::Variant::Map my_map; string error(" unknown "); if (event.getDataCount() >= 1) { my_map = event.getData(0).getProperties(); error = (string)event.getData(0).getProperty("error_text"); } qb_log(LOG_ERR, "%s'ing: EXCEPTION %s ", ar->method.c_str(), error.c_str()); method_response(ar, my_map, RPC_EXCEPTION); _outstanding_calls.erase(event.getCorrelator()); ar->unref(); } } else if (event.getType() == CONSOLE_EVENT) { if (_event_fn != NULL) { _event_fn(event, _event_user_data); } } return true; }
void QmfObject::method_call_async(std::string method, qpid::types::Variant::Map in_args, void *user_data, uint32_t timeout_ms) { uint32_t correlation_id; QmfAsyncRequest *ar; if (_method_response_fn == NULL) { qb_log(LOG_WARNING, "can't do async call without response callback"); return; } ar = new QmfAsyncRequest(); ar->method = method; ar->args = in_args; ar->obj = this; ar->user_data = user_data; ar->timeout = timeout_ms; if (_connected) { qb_loop_timer_handle th; Agent a = _qmf_data.getAgent(); correlation_id = a.callMethodAsync(method, in_args, _qmf_data.getAddr()); _outstanding_calls[correlation_id] = ar; g_timer_stop(ar->time_queued); g_timer_start(ar->time_execed); ar->state = QmfAsyncRequest::JOB_RUNNING; ar->ref(); mainloop_timer_add(timeout_ms, ar, method_call_tmo, &th); } else { ar->state = QmfAsyncRequest::JOB_SCHEDULED; g_timer_start(ar->time_queued); _pending_jobs.push_back(ar); } }