| GENERAL NOTES | |
| ===================================================================== | |
| FAQ | |
| ===================================================================== | |
| 1. Q: where is the server accept loop, and what causes the loop to exit? | |
| A. the accept loop is etch_tcpsvr_acceptproc(). | |
| destroy_etch_listener() forces the main listener thread down | |
| via etch_tcpsvr_close(svr); in destroy_etch_listener. | |
| 2. Q. how do we message the accept? | |
| A. i_sessionlistener->transport_control. | |
| 3. a. the specific transport's (tcpserver's) "session" interface is the i_sessionlistener. | |
| b. the i_sessionlistener.thisx is be the etch_tcpserver. | |
| c. and the i_sessionlistener.transport is how we message the main listener. | |
| d. session.mainlistener is the i_sessionlistener. | |
| 4. Q: where is server shutdown recognized? | |
| A: etch_tcpserver_listenerproc(), is_shutdown_request = TRUE; svr->is_started = FALSE; | |
| and BREAK out of receive loop. | |
| 5. Q. where do we catch server's main listener exit? | |
| A. xxxx_helper: xxxx_listener_start(); etchlog ("main listener exited\n"); | |
| A. etch_tcpserver: etch_tcpserver_listenerproc(); catch result of transport_control(STOP | |
| 6. Q. where is server's receive thread recognized? | |
| A. etch_tcpsvr_acceptproc() | |
| 7. Q. how is the server receive thread object accessed in the generic transport context? | |
| A. params.session[i].cx.thread | |
| 8. Q. how could we programmatically stop the server main listener from the server's main thread? | |
| A. listener->transport_control (listener->thisx, STOP_WAITDOWN, ms); | |
| 9. Q. where is the receive loop (data from other side)? | |
| A. tcpserver: at etch_tcpserver_listenerproc; line: etch_tcpclient_receive(); | |
| tcpconxn: at etch_tcpclient_receivex; line: apr_socket_recv() | |
| 10. Q. how is data received off the socket routed? | |
| A. etcpconxn: at etch_tcpclient_receivex; line: cx->on_data (tcpx, 0, datalen, buf); | |
| 11. Q. where are the tcp connection, packetizer, messagizer, mailbox manager, | |
| and delivery service instantiated? | |
| A. etch_transport: new_tcp_delivery_service() | |
| 12. Q. how is the inter-layer messaging chain constructed? | |
| A. a) each layer implements both a session interface and a transport interface, and hosts | |
| a session and a transport interface owned by another layer, its session owned by the | |
| adjacent higher layer, its transport owned by the adjacent lower layer. | |
| b) each layer's constructor is passed the transport implementation of the next lower layer, | |
| and sets its own transport to the passed transport interface. | |
| c) each layer implements its own session interface, and its constructor sets the session | |
| of the next lower layer, to its own session interface implementation. | |
| d) the thisx pointers of the hosted session and transport interfaces, are the layer objects | |
| which implemented those interfaces. for example, packetizer.session is the session | |
| interface implemented by messagizer, and so messagizer.session.thisx is the messagizer. | |
| 13. Q. what is the messaging stack hierarchy? | |
| A. as follows, transport messaging traveling down towards zero, session messaging traveling up: | |
| 1. tcp connection | |
| 2. packetizer | |
| 3. messagizer | |
| 4. mailbox manager | |
| 5. delivery service | |
| 6. stub | |
| 7. stub user interface | |
| 14. Q. where is the client receive thread constructed, and what is the receive procedure? | |
| A. etch_tcp_client* new_tcp_client (etch_tcp_connection*), called from etch_tcpclient_start_listener(); | |
| the receive proc is etch_tcpclient_listenerproc() | |
| 15. Q. where is the tcp client receive listener stopped? | |
| A. etch_tcpclient_stop_listener(), called from etch_tcpconx_transport_control(), case CLASSID_CONTROL_STOP. | |
| ============================================================ | |
| debugger breakpoints to catch significant events on SERVER | |
| ============================================================ | |
| ### MODULE FUNCTION LINE | |
| --- ---------------------- ------------------------------ ------------------------------------------------------------- | |
| 1. etch_transport new_etch_listener i_sessionlistener* l = new_sessionlistener_interface | |
| 2. xxxx_listener_main _tmain xxxx_listener_start (listener, waitupms); | |
| 3. xxxx_helper xxxx_listener_start listener->transport_control (START_WAITUP) | |
| 4. etch_tcpserver etch_tcpsvr_acceptproc apr_socket_accept (&newsock, ... | |
| 5. xxxx_helper xxxx_listener_start listener->wait_exit (listener); | |
| 6. NOW BLOCKING WAITING FOR CONNECTION - SEND CONNECT AND DATA | |
| 7. etch_tcpserver etch_tcpsvr_acceptproc newx = new_accepted_tcp_connection (hostname, ... | |
| 8. etch_tcpserver etch_tcpsvr_acceptproc tcpserver->on_session_accepted (... | |
| 9. etch_transport tcpxfact_session_accepted delivery_service = new_etch_transport_a ( | |
| 10. etch_transport tcpxfact_session_accepted delivery_service->itm->transport_control (START | |
| 11. etch_tcpserver etch_tcpsvr_acceptproc thread = svr->threadpool->run(etch_tcpserver_listenerproc | |
| 12a. etch_tcpserver etch_tcpserver_listenerproc mainlistener->transport_control (STOP_WAITDOWN | |
| 12b. etch_tcpserver etch_tcpserver_listenerproc ETCHOBJ_DESTROY(cx->session); | |
| 13. etch_tcpserver etch_tcpsvr_acceptproc return | |
| 14. xxxx_helper xxxx_listener_start etchlog ("main listener exited\n"); | |
| 15. etch_tcpserver etch_tcpserver_listenerproc catch result of transport_control(STOP_WAITDOWN | |
| 16. xxxx_listener_main _tmain ETCHOBJ_DESTROY(listener); | |
| 17. SERVER EXE EXITS | |
| ===================================================================== | |
| debugger breakpoints to catch the most siginificant events on CLIENT | |
| ===================================================================== | |
| ### MODULE FUNCTION LINE | |
| --- ---------------------- ------------------------------ ------------------------------------------------------------- | |
| 1. xxxx_helper start_perf_client remote = new_remote_server () | |
| 2. xxxx_helper new_remote_server remote_server = new_xxxx_remote_server () | |
| 3. xxxx_remote_server new_xxxx_remote_server rs->server_base = new_xxxx_remote_server_base () | |
| 4. xxxx_helper new_remote_server myclient = p->new_client (remote_server); | |
| 5. xxxx_client_implx init_xxxx_client_impl pc->xxxx_client_base = new_xxxx_client_base (pc); | |
| 6. xxxx_helper new_remote_server client_stub = new_perf_client_stub () | |
| 7. etch_stub new_stubimpl_init newstub->stub_base = new_stub () | |
| 8. xxxx_helper new_remote_server return | |
| 9. etch_remote etchremote_start_waitup return thisx->transport_control(START_WAITUP) | |
| 10. etch_transport tcpdelsvc_transport_control dstransport->transport_control() | |
| 11. etch_tcpconxn etch_tcpconx_start return etch_tcpconx_open () | |
| 12 . xxxx_helper start_xxxx_client remote->destroy(remote); | |
| 13. xxxx_remote_server destroy_perf_remote_server ETCHOBJ_DESTROY(thisx->remote_base); | |
| 14. xxxx_remote_server destroy_perf_remote_server ETCHOBJ_DESTROY(thisx->server_base); | |
| 15. xxxx_remote_server destroy_perf_remote_server ETCHOBJ_DESTROY(thisx->client_factory); | |
| 14. etch_transport destroy_etch_client_factory ETCHOBJ_DESTROY(((objmask*)thisx->iclient)); | |
| 14. etch_transport destroy_etch_client_factory ETCHOBJ_DESTROY(((objmask*)thisx->stub)); | |
| 14. etch_transport destroy_etch_client_factory ETCHOBJ_DESTROY(((objmask*)thisx->dsvc)); | |
| 15. xxxx_client_main _tmain if (NULL == remote) break; | |
| 17. CLIENT EXE EXITS | |
| ===================================================================== | |
| Notes on message functionality thread execution | |
| ===================================================================== | |
| 1. The stub's session i/f becomes the delivery's session in the stub base ctor. | |
| 2. The delivery's session is typed to SessionMessage. The setSession sets the | |
| entire session object, which in this case is a SessionMessage. So setting | |
| the delivery's session also sets its SessionMessage method. | |
| a. This means we need to override set_session on all objects whose session | |
| i/f augments i_session. | |
| 3. Therefore, calling session_message on the transport (delivery) invokes the | |
| stub's session_message. | |
| 4. The stub's session_message expects as a parameter, a message to be "executed", | |
| either on a pool thread or inline. | |
| 5. stubbase.session_message : inline execute mode | |
| a. type.stub_helper().run (delivery*, _obj, whofrom, msg) | |
| this translates to: | |
| result = stubhelper(stub, delivery, obj, sender, msg); | |
| b. stubhelper's are implemented in the xxxx_server_stub, e.g. perf_server_stub. | |
| c. the perf_server_stub stubhelper for the type for perf.add() is as follows: | |
| static int run (stub, delivery, i_perf_server* perf, whofrom, msg) | |
| { | |
| etch_message* rmsg = message_get_in_reply_to(msg); | |
| etch_int32* x = message_get msg, perfv._mf_x); | |
| etch_int32* y = .... | |
| etch_int32* addresult = perf->add (perf, x, y); | |
| etch_field* key = builtins._mf_result; /* todo: get from perfvf instead, where to get vf? */ | |
| result = message_put (rsmg, key, key, addresult); | |
| // if result bad, transport an exception | |
| result = delivery->itm->transport_message (delivery, whofrom, rmsg); | |
| } | |