Skip to content

Commit df5ed87

Browse files
authored
[C] refactor response client/server code to separate out CLI code (#1576)
* [C] refactor response client/server code to separate out CLI code * [C] fix null client issue, address (hopefully) snprintf issue * [C] fix strncpy size
1 parent 51e0009 commit df5ed87

2 files changed

Lines changed: 467 additions & 278 deletions

File tree

aeron-samples/src/main/c/response/response_client.c

Lines changed: 173 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,30 @@
3434
#include "util/aeron_parse_util.h"
3535
#include "util/aeron_strutil.h"
3636
#include "aeron_agent.h"
37+
#include "aeron_alloc.h"
3738

3839
#include "../samples_configuration.h"
3940
#include "../sample_util.h"
4041

42+
typedef struct response_client_stct response_client_t;
43+
44+
int response_client_create(
45+
response_client_t **response_clientp,
46+
aeron_t *aeron,
47+
aeron_fragment_handler_t delegate,
48+
const char *request_channel,
49+
int32_t request_stream_id,
50+
const char *response_control_channel,
51+
int32_t response_stream_id);
52+
53+
void response_client_delete(response_client_t *response_client);
54+
55+
int64_t response_client_offer(response_client_t *response_client, const uint8_t *buffer, size_t length);
56+
57+
bool response_client_is_connected(response_client_t *response_client);
58+
59+
int response_client_do_work(response_client_t *response_client);
60+
4161
const char usage_str[] =
4262
"[-h][-v][-c request-uri][-d response-uri][-l linger][-m messages][-p prefix][-r response-stream-id][-s request-stream-id]\n"
4363
" -h help\n"
@@ -49,7 +69,7 @@ const char usage_str[] =
4969
" -p prefix aeron.dir location specified as prefix\n"
5070
" -r response-stream-id response stream-id to use\n"
5171
" -s request-stream-id request stream-id to use\n"
52-
;
72+
;
5373

5474
volatile bool running = true;
5575

@@ -100,21 +120,15 @@ int main(int argc, char **argv)
100120
const char *aeron_dir = NULL;
101121
aeron_t *aeron = NULL;
102122

103-
aeron_async_add_subscription_t *async_add_sub = NULL;
104-
aeron_subscription_t *subscription = NULL;
105-
aeron_fragment_assembler_t *fragment_assembler = NULL;
106123
const char *response_control_channel = DEFAULT_RESPONSE_CONTROL_CHANNEL;
107124
int32_t response_stream_id = DEFAULT_RESPONSE_STREAM_ID;
108-
int64_t subscriber_registration_id;
109-
110-
aeron_async_add_publication_t *async_add_pub = NULL;
111-
aeron_publication_t *publication = NULL;
112125
const char *request_channel = DEFAULT_REQUEST_CHANNEL;
113126
int32_t request_stream_id = DEFAULT_REQUEST_STREAM_ID;
114-
115127
uint64_t linger_ns = DEFAULT_LINGER_TIMEOUT_MS * UINT64_C(1000) * UINT64_C(1000);
116128
uint64_t messages = DEFAULT_NUMBER_OF_MESSAGES;
117129

130+
response_client_t *response_client = NULL;
131+
118132
while ((opt = getopt(argc, argv, "hvc:d:l:m:p:r:s:")) != -1)
119133
{
120134
switch (opt)
@@ -191,7 +205,6 @@ int main(int argc, char **argv)
191205

192206
signal(SIGINT, sigint_handler);
193207

194-
195208
if (aeron_context_init(&context) < 0)
196209
{
197210
fprintf(stderr, "aeron_context_init: %s\n", aeron_errmsg());
@@ -219,94 +232,27 @@ int main(int argc, char **argv)
219232
goto cleanup;
220233
}
221234

235+
if (response_client_create(
236+
&response_client,
237+
aeron,
238+
poll_handler,
239+
request_channel,
240+
request_stream_id,
241+
response_control_channel,
242+
response_stream_id) < 0)
222243
{
223-
char _response_channel_buf[AERON_MAX_PATH] = { 0 };
224-
225-
SNPRINTF(_response_channel_buf, sizeof(_response_channel_buf) - 1, "%s|control-mode=response", response_control_channel);
226-
227-
printf("Subscribing to response channel %s on Stream ID %" PRId32 "\n", _response_channel_buf, response_stream_id);
228-
229-
if (aeron_async_add_subscription(
230-
&async_add_sub,
231-
aeron,
232-
_response_channel_buf,
233-
response_stream_id,
234-
print_available_image,
235-
NULL,
236-
print_unavailable_image,
237-
NULL) < 0)
238-
{
239-
fprintf(stderr, "aeron_async_add_subscription: %s\n", aeron_errmsg());
240-
goto cleanup;
241-
}
242-
}
243-
244-
while (NULL == subscription)
245-
{
246-
if (aeron_async_add_subscription_poll(&subscription, async_add_sub) < 0)
247-
{
248-
fprintf(stderr, "aeron_async_add_subscription_poll: %s\n", aeron_errmsg());
249-
goto cleanup;
250-
}
251-
252-
sched_yield();
253-
}
254-
255-
printf("Subscription channel status %" PRIu64 "\n", aeron_subscription_channel_status(subscription));
256-
257-
if (aeron_fragment_assembler_create(&fragment_assembler, poll_handler, subscription) < 0)
258-
{
259-
fprintf(stderr, "aeron_fragment_assembler_create: %s\n", aeron_errmsg());
244+
fprintf(stderr, "response_client_create: %s\n", aeron_errmsg());
260245
goto cleanup;
261246
}
262247

263-
{
264-
aeron_subscription_constants_t constants;
265-
266-
if (aeron_subscription_constants(subscription, &constants) < 0)
267-
{
268-
fprintf(stderr, "aeron_subscription_constants: %s\n", aeron_errmsg());
269-
goto cleanup;
270-
}
271-
272-
subscriber_registration_id = constants.registration_id;
273-
}
274-
275-
{
276-
char _channel_buf[AERON_MAX_PATH] = { 0 };
277-
278-
SNPRINTF(_channel_buf, sizeof(_channel_buf) - 1, "%s|response-correlation-id=%" PRIi64, request_channel, subscriber_registration_id);
279-
280-
printf("Publishing to channel %s on Stream ID %" PRId32 "\n", _channel_buf, request_stream_id);
281-
282-
if (aeron_async_add_publication(&async_add_pub, aeron, _channel_buf, request_stream_id) < 0)
283-
{
284-
fprintf(stderr, "aeron_async_add_publication: %s\n", aeron_errmsg());
285-
goto cleanup;
286-
}
287-
}
288-
289-
while (NULL == publication)
290-
{
291-
if (aeron_async_add_publication_poll(&publication, async_add_pub) < 0)
292-
{
293-
fprintf(stderr, "aeron_async_add_publication_poll: %s\n", aeron_errmsg());
294-
goto cleanup;
295-
}
296-
297-
sched_yield();
298-
}
299-
300-
printf("Publication channel status %" PRIu64 "\n", aeron_publication_channel_status(publication));
301-
302248
for (size_t i = 0; i < messages && is_running(); i++)
303249
{
304250
message_len = SNPRINTF(small_message, sizeof(small_message) - 1, "Hello World! %" PRIu64, (uint64_t)i);
305251
message = small_message;
306252
printf("offering %" PRIu64 "/%" PRIu64 " - ", (uint64_t)i, (uint64_t)messages);
307253
fflush(stdout);
308254

309-
int64_t result = aeron_publication_offer(publication, (const uint8_t *)message, message_len, NULL, NULL);
255+
int64_t result = response_client_offer(response_client, (const uint8_t *)message, message_len);
310256

311257
if (result > 0)
312258
{
@@ -333,15 +279,14 @@ int main(int argc, char **argv)
333279
printf("Offer failed due to unknown reason %" PRId64 "\n", result);
334280
}
335281

336-
if (!aeron_publication_is_connected(publication))
282+
if (!response_client_is_connected(response_client))
337283
{
338284
printf("No active subscribers detected\n");
339285
}
340286

341287
aeron_nano_sleep(1000ul * 1000ul * 1000ul);
342288

343-
int fragments_read = aeron_subscription_poll(
344-
subscription, aeron_fragment_assembler_handler, fragment_assembler, DEFAULT_FRAGMENT_COUNT_LIMIT);
289+
int fragments_read = response_client_do_work(response_client);
345290

346291
if (fragments_read < 0)
347292
{
@@ -359,13 +304,148 @@ int main(int argc, char **argv)
359304
}
360305

361306
cleanup:
362-
aeron_subscription_close(subscription, NULL, NULL);
363-
aeron_publication_close(publication, NULL, NULL);
307+
response_client_delete(response_client);
364308
aeron_close(aeron);
365309
aeron_context_close(context);
366-
aeron_fragment_assembler_delete(fragment_assembler);
367310

368311
return status;
369312
}
370313

371314
extern bool is_running(void);
315+
316+
struct response_client_stct
317+
{
318+
aeron_t *aeron;
319+
aeron_subscription_t *subscription;
320+
aeron_fragment_assembler_t *fragment_assembler;
321+
aeron_publication_t *publication;
322+
};
323+
324+
int response_client_create(
325+
response_client_t **response_clientp,
326+
aeron_t *aeron,
327+
aeron_fragment_handler_t delegate,
328+
const char *request_channel,
329+
int32_t request_stream_id,
330+
const char *response_control_channel,
331+
int32_t response_stream_id)
332+
{
333+
response_client_t *response_client;
334+
aeron_async_add_subscription_t *async_add_sub;
335+
aeron_async_add_publication_t *async_add_pub;
336+
char _response_channel_buf[AERON_MAX_PATH] = { 0 };
337+
char _channel_buf[AERON_MAX_PATH] = { 0 };
338+
int64_t subscriber_registration_id;
339+
aeron_subscription_constants_t constants;
340+
341+
aeron_alloc((void **)&response_client, sizeof(response_client_t));
342+
343+
SNPRINTF(_response_channel_buf, sizeof(_response_channel_buf) - 1, "%s|control-mode=response", response_control_channel);
344+
345+
printf("Subscribing to response channel %s on Stream ID %" PRId32 "\n", _response_channel_buf, response_stream_id);
346+
347+
if (aeron_async_add_subscription(
348+
&async_add_sub,
349+
aeron,
350+
_response_channel_buf,
351+
response_stream_id,
352+
print_available_image,
353+
NULL,
354+
print_unavailable_image,
355+
NULL) < 0)
356+
{
357+
fprintf(stderr, "aeron_async_add_subscription: %s\n", aeron_errmsg());
358+
goto cleanup;
359+
}
360+
361+
response_client->subscription = NULL;
362+
while (NULL == response_client->subscription)
363+
{
364+
if (aeron_async_add_subscription_poll(&response_client->subscription, async_add_sub) < 0)
365+
{
366+
fprintf(stderr, "aeron_async_add_subscription_poll: %s\n", aeron_errmsg());
367+
goto cleanup;
368+
}
369+
370+
sched_yield();
371+
}
372+
373+
printf("Subscription channel status %" PRIu64 "\n", aeron_subscription_channel_status(response_client->subscription));
374+
375+
if (aeron_fragment_assembler_create(&response_client->fragment_assembler, delegate, response_client->subscription) < 0)
376+
{
377+
fprintf(stderr, "aeron_fragment_assembler_create: %s\n", aeron_errmsg());
378+
goto cleanup;
379+
}
380+
381+
if (aeron_subscription_constants(response_client->subscription, &constants) < 0)
382+
{
383+
fprintf(stderr, "aeron_subscription_constants: %s\n", aeron_errmsg());
384+
goto cleanup;
385+
}
386+
387+
subscriber_registration_id = constants.registration_id;
388+
389+
SNPRINTF(_channel_buf, sizeof(_channel_buf) - 1, "%s|response-correlation-id=%" PRIi64, request_channel, subscriber_registration_id);
390+
391+
printf("Publishing to channel %s on Stream ID %" PRId32 "\n", _channel_buf, request_stream_id);
392+
393+
if (aeron_async_add_publication(&async_add_pub, aeron, _channel_buf, request_stream_id) < 0)
394+
{
395+
fprintf(stderr, "aeron_async_add_publication: %s\n", aeron_errmsg());
396+
goto cleanup;
397+
}
398+
399+
while (NULL == response_client->publication)
400+
{
401+
if (aeron_async_add_publication_poll(&response_client->publication, async_add_pub) < 0)
402+
{
403+
fprintf(stderr, "aeron_async_add_publication_poll: %s\n", aeron_errmsg());
404+
goto cleanup;
405+
}
406+
407+
sched_yield();
408+
}
409+
410+
printf("Publication channel status %" PRIu64 "\n", aeron_publication_channel_status(response_client->publication));
411+
412+
*response_clientp = response_client;
413+
414+
return 0;
415+
416+
cleanup:
417+
response_client_delete(response_client);
418+
419+
return -1;
420+
}
421+
422+
void response_client_delete(response_client_t *response_client)
423+
{
424+
if (NULL != response_client)
425+
{
426+
aeron_subscription_close(response_client->subscription, NULL, NULL);
427+
aeron_publication_close(response_client->publication, NULL, NULL);
428+
aeron_fragment_assembler_delete(response_client->fragment_assembler);
429+
430+
aeron_free(response_client);
431+
}
432+
}
433+
434+
int64_t response_client_offer(response_client_t *response_client, const uint8_t *buffer, size_t length)
435+
{
436+
return aeron_publication_offer(response_client->publication, buffer, length, NULL, NULL);
437+
}
438+
439+
bool response_client_is_connected(response_client_t *response_client)
440+
{
441+
return aeron_publication_is_connected(response_client->publication);
442+
}
443+
444+
int response_client_do_work(response_client_t *response_client)
445+
{
446+
return aeron_subscription_poll(
447+
response_client->subscription,
448+
aeron_fragment_assembler_handler,
449+
response_client->fragment_assembler,
450+
DEFAULT_FRAGMENT_COUNT_LIMIT);
451+
}

0 commit comments

Comments
 (0)