static void _freeSubscription(natsSubscription *sub) { natsMsg *m; if (sub == NULL) return; while ((m = sub->msgList.head) != NULL) { sub->msgList.head = m->next; natsMsg_Destroy(m); } NATS_FREE(sub->subject); NATS_FREE(sub->queue); natsTimer_Destroy(sub->signalTimer); if (sub->deliverMsgsThread != NULL) { natsThread_Detach(sub->deliverMsgsThread); natsThread_Destroy(sub->deliverMsgsThread); } natsCondition_Destroy(sub->cond); natsMutex_Destroy(sub->mu); natsConn_release(sub->conn); NATS_FREE(sub); }
static void onMsg(natsConnection *nc, natsSubscription *sub, natsMsg *msg, void *closure) { // This callback will be invoked with a NULL message when the // subscription times out. if (print && (msg != NULL)) printf("Received msg: %s - %.*s\n", natsMsg_GetSubject(msg), natsMsg_GetDataLength(msg), natsMsg_GetData(msg)); // We should be using a mutex to protect those variables since // they are used from the subscription's delivery and the main // threads. For demo purposes, this is fine. if ((msg == NULL) || (++count == total)) { printf("%s, destroying subscription\n", (msg == NULL ? "Subscription timed-out" : "All messages received")); natsSubscription_Destroy(sub); done = true; } // It is safe to call natsMsg_Destroy() with a NULL message. natsMsg_Destroy(msg); }
static void onMsg(natsConnection *nc, natsSubscription *sub, natsMsg *msg, void *closure) { if (print) printf("Received msg: %s - %.*s\n", natsMsg_GetSubject(msg), natsMsg_GetDataLength(msg), natsMsg_GetData(msg)); if (start == 0) start = nats_Now(); // We should be using a mutex to protect those variables since // they are used from the subscription's delivery and the main // threads. For demo purposes, this is fine. if (++count == total) elapsed = nats_Now() - start; natsMsg_Destroy(msg); }
int main(int argc, char **argv) { natsConnection *conn = NULL; natsOptions *opts = NULL; natsSubscription *sub = NULL; natsStatistics *stats = NULL; natsMsg *msg = NULL; natsStatus s; opts = parseArgs(argc, argv, usage); printf("Listening %ssynchronously on '%s' with name '%s'.\n", (async ? "a" : ""), subj, name); s = natsOptions_SetErrorHandler(opts, asyncCb, NULL); if (s == NATS_OK) s = natsConnection_Connect(&conn, opts); if (s == NATS_OK) { if (async) s = natsConnection_QueueSubscribe(&sub, conn, subj, name, onMsg, NULL); else s = natsConnection_QueueSubscribeSync(&sub, conn, subj, name); } // For maximum performance, set no limit on the number of pending messages. if (s == NATS_OK) s = natsSubscription_SetPendingLimits(sub, -1, -1); if (s == NATS_OK) s = natsSubscription_AutoUnsubscribe(sub, (int) total); if (s == NATS_OK) s = natsStatistics_Create(&stats); if ((s == NATS_OK) && async) { while (s == NATS_OK) { s = printStats(STATS_IN|STATS_COUNT,conn, sub, stats); if (count == total) break; if (s == NATS_OK) nats_Sleep(1000); } } else if (s == NATS_OK) { int64_t last = 0; for (count = 0; (s == NATS_OK) && (count < total); count++) { s = natsSubscription_NextMsg(&msg, sub, 10000); if (s != NATS_OK) break; if (start == 0) start = nats_Now(); if (nats_Now() - last >= 1000) { s = printStats(STATS_IN|STATS_COUNT,conn, sub, stats); last = nats_Now(); } natsMsg_Destroy(msg); } } if (s == NATS_OK) { printPerf("Received", total, start, elapsed); } else { printf("Error: %d - %s\n", s, natsStatus_GetText(s)); nats_PrintLastErrorStack(stderr); } // Destroy all our objects to avoid report of memory leak natsStatistics_Destroy(stats); natsSubscription_Destroy(sub); natsConnection_Destroy(conn); natsOptions_Destroy(opts); // To silence reports of memory still in used with valgrind nats_Close(); return 0; }