/** * initialize children */ static int child_init(int rank) { int i, newpid; if (rank == PROC_MAIN) { /* fork worker processes */ for(i = 0; i < num_workers; i++) { init_worker(&workers[i]); LM_DBG("starting worker process %d\n", i); newpid = fork_process(PROC_NOCHLDINIT, "DMQ WORKER", 0); if(newpid < 0) { LM_ERR("failed to form process\n"); return -1; } else if(newpid == 0) { /* child - this will loop forever */ worker_loop(i); } else { workers[i].pid = newpid; } } /* notification_node - the node from which the Kamailio instance * gets the server list on startup. * the address is given as a module parameter in dmq_notification_address * the module MUST have this parameter if the Kamailio instance is not * a master in this architecture */ if(dmq_notification_address.s) { notification_node = add_server_and_notify(&dmq_notification_address); if(!notification_node) { LM_ERR("cannot retrieve initial nodelist from %.*s\n", STR_FMT(&dmq_notification_address)); return -1; } } return 0; } if(rank == PROC_INIT || rank == PROC_TCP_MAIN) { /* do nothing for the main process */ return 0; } pid = my_pid(); return 0; }
/** * @brief pings the servers in the nodelist * * if the server does not reply to the ping, it is removed from the list * the ping messages are actualy notification requests * this way the ping will have two uses: * - checks if the servers in the list are up and running * - updates the list of servers from the other nodes */ void ping_servers(unsigned int ticks, void *param) { str *body; int ret; LM_DBG("ping_servers\n"); if(!node_list->nodes || (node_list->nodes->local && !node_list->nodes->next)) { LM_DBG("node list is empty - attempt to rebuild from notification " "address\n"); *dmq_init_callback_done = 0; if(dmq_notification_address.s) { notification_node = add_server_and_notify(&dmq_notification_address); if(!notification_node) { LM_ERR("cannot retrieve initial nodelist from %.*s\n", STR_FMT(&dmq_notification_address)); } } else { LM_ERR("no notification address"); } return; } body = build_notification_body(); if(!body) { LM_ERR("could not build notification body\n"); return; } ret = bcast_dmq_message1(dmq_notification_peer, body, NULL, ¬ification_callback, 1, ¬ification_content_type, 1); pkg_free(body->s); pkg_free(body); if(ret < 0) { LM_ERR("error broadcasting message\n"); } }