Re: Asynchronous BEEP draft status
"Sam Roberts" <[email protected]> Wed, 26 Nov 2008 11:11:35 -0800
| Newsgroups | gmane.ietf.beep |
|---|---|
| Message-ID | <[email protected]> |
On Wed, Nov 26, 2008 at 10:17 AM, Sam Roberts <[email protected]> wrote: > a - This draft describes how to build into BEEP something you can > already do with BEEP (several ways). > > I can write a trivial example using vortex that implements the > motivating use-case for those unconvinced. Sorry. Couldn't resist implementing this. Draft states following use case: """ Asynchronous applications require a protocol that is able to support a large number of concurrent outstanding requests. The analogy of a channel as a thread does not scale to the large number of threads used in modern systems. Modern applications regularly have large numbers of concurrent processing threads. Thus, a better way of multiplexing large numbers of concurrent requests is required. This document describes an BEEP feature, an extension to BEEP, that enables the creation of an asynchronous channel. An asynchronous channel is a channel where response ordering is not fixed to the order of the requests sent by the client peer. An asynchronous channel is identical to other channels, using unmodified framing; only requests may be processed in parallel and responses may be sent in any order. """ Note that Vortex delivers each MSG on a seperate thread, exactly as described above. BEEP msgnos are ordered across a channel, of course, but application msgs can be replied whenever you want. The profile designer specifies the content and meaning of beep message payload. Profile designers are not required to map BEEP internal msgno 1-to-1 to their profile's message identifiers. Often, this is convenient. When it is not convenient, don't do it. Server: #include <vortex.h> #define PROFILE "http://example.com/beep/delayed" /* MSG payload is msgid server waits a random amount of time, and sends reply. RPY payload is "msgid delay", where msgid is the msgid of the request being responded to, and delay is how long the server delayed before sending the reply. Actual code might put msgid in a MIME header, and the payload would be the request information. Or the request would be xml encoded, and include a msgid. There are lots of variations of this, none of them requiring extending the BEEP protocol. */ VortexQueue* msgno_queue; void frame_received(VortexChannel* chan, VortexConnection* conn, VortexFrame* frame, void*v) { int msgno = vortex_frame_get_msgno (frame); int delay = (rand() % 30) + 1; char* msgid = vortex_frame_get_payload(frame); char str[128]; vortex_queue_push(msgno_queue, INT_TO_PTR(msgno)); printf("msgno %d msgid %s delay %d\n", msgno, msgid, delay); sleep(delay); msgno = PTR_TO_INT(vortex_queue_pop(msgno_queue)); sprintf(str, "%s %d", msgid, delay); vortex_channel_send_rpy(chan, str, strlen(str), msgno); } const char USAGE[] = "usage: %s <port>"; int main(int argc, char ** argv) { if(!argv[1]) { printf("%s\n", USAGE); return 1; } msgno_queue = vortex_queue_new(); vortex_init(); vortex_log_enable(1); vortex_profiles_register(PROFILE, NULL, NULL, NULL, NULL, frame_received, NULL); vortex_listener_new("0.0.0.0", argv[1], NULL, NULL); vortex_listener_wait(); vortex_exit(); return 0; } Client: #include <vortex.h> #include <assert.h> #define PROFILE "http://example.com/beep/delayed" int msgid = 0; void send_msg(VortexChannel* channel) { int ok = vortex_channel_send_msgv(channel, 0, "%d", ++msgid); assert(ok); } void on_frame(VortexChannel* channel, VortexConnection* conn, VortexFrame* frame, void* v) { int msgno = vortex_frame_get_msgno(frame); const char* content = vortex_frame_get_payload(frame); printf("(msgno %d) %s\n", msgno, content); send_msg(channel); } int main (int argc, char ** argv) { VortexConnection * connection = NULL; VortexChannel * channel = NULL; vortex_init (); connection = vortex_connection_new(argv[1], argv[2], NULL, NULL); if (!vortex_connection_is_ok(connection, false)) { fprintf(stderr, "Unable to connect remote server, error was: %s\n", vortex_connection_get_message(connection)); return 1; } channel = vortex_channel_new(connection, 0, PROFILE, NULL, NULL, /* no close handling */ on_frame, NULL, NULL, NULL /* no async channel creation */ ); if (channel == NULL) { fprintf(stderr, "Unable to create the channel..\n"); return 1; } printf(".. send msg\n"); send_msg(channel); send_msg(channel); send_msg(channel); send_msg(channel); send_msg(channel); { char c; read(0, &c, 1); } vortex_exit (); return 0 ; } Client output: % ./async-client localhost 3333 .. send msg (msgno 0) 3 28 (msgno 1) 1 14 (msgno 2) 2 17 (msgno 3) 5 24 (msgno 4) 4 26 (msgno 5) 10 2 (msgno 6) 11 3 (msgno 7) 9 10 (msgno 8) 8 13 (msgno 9) 12 8 Not BEEP msgno order is maintained, application msg order is asynchronous. Cheers, Sam