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+
4161const 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
5474volatile 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
361306cleanup :
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
371314extern 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