Service_logger, skynet_error, and skynet source code analysis,

Source: Internet
Author: User

Service_logger, skynet_error, and skynet source code analysis,

The service_srv directory is a c service template attached to the skynet core module, such as the logger service used for log output and the snlua service used to run lua scripts. It is compiled into the so library for use by the skynet framework. The logger Service (service_logger.c) has simple functions and is familiar with skynet workflow by understanding its working methods. When skynet is started, a "logger" service is started. By default, it is a logger-type service. Of course, it can be configured as snlua.

//skynet_start.cstruct skynet_context *ctx = skynet_context_new(config->logservice, config->logger) //skynet_main.cconfig.logger = optstring("logger", NULL);config.logservice = optstring("logservice", "logger");

Start a new logger service, call the logger_create api, apply for a struct logger structure, and assign the value to ctx-> instance. After the service exits, logger_release is called to clear and recycle logger_release.

Struct logger {FILE * handle; // FILE handle char * filename; int close; // 0 indicates that the FILE handle is standard output, and 1 indicates that the FILE is output to the FILE }; struct logger * logger_create (void) {struct logger * inst = skynet_malloc (sizeof (* inst); inst-> handle = NULL; inst-> close = 0; inst-> filename = NULL; return inst ;}

The logger_init api will be called later. The parameter param is config-> logger in the configuration. If the file path is specified, the file will be opened, inst-> handle = fopen (parm, "w"); otherwise, set the file handle to the standard output inst-> handle = stdout. Finally, set the message callback function of ctx to logger_cb (skynet_callback) and register skynet_command (ctx, "REG", ". logger") for ctx "). Later, let's look at the message callback function logger_cb.

int logger_init(struct logger * inst, struct skynet_context *ctx, const char * parm) {        if (parm) {                inst->handle = fopen(parm,"w");                if (inst->handle == NULL) {                        return 1;                }                inst->filename = skynet_malloc(strlen(parm)+1);                strcpy(inst->filename, parm);                inst->close = 1;        } else {                inst->handle = stdout;        }        if (inst->handle) {                skynet_callback(ctx, inst, logger_cb);                skynet_command(ctx, "REG", ".logger");                return 0;        }        return 1;}

The skynet output log usually calls the skynet_error api (skynet. error is used in the lua layer, and skynet_error is also called at the end ). Search for the handle id of ctx corresponding to "logger", and send the skynet_context_push message package to the id. the type of the message package is PTYPE_TEXT. If the PTYPE_ALLOCSESSION tag is not set, the receiver is not required to return the message.

//skynet_error.c
void skynet_error(struct skynet_context * context, const char *msg, ...) { static uint32_t logger = 0; if (logger == 0) { logger = skynet_handle_findname("logger"); } ... struct skynet_message smsg; if (context == NULL) { smsg.source = 0; } else { smsg.source = skynet_context_handle(context); } smsg.session = 0; smsg.data = data; smsg.sz = len | ((size_t)PTYPE_TEXT << MESSAGE_TYPE_SHIFT); skynet_context_push(logger, &smsg);}

When a worker thread distributes the message package, the message callback function logger_cb of the logger service is called. The interface parameters of message callback functions of different service types are the same.

static int logger_cb(struct skynet_context * context, void *ud, int type, int session, uint32_t source, const void * msg, size_t sz) {        struct logger * inst = ud;        switch (type) {        case PTYPE_SYSTEM:                if (inst->filename) {                        inst->handle = freopen(inst->filename, "a", inst->handle);                }                break;        case PTYPE_TEXT:                fprintf(inst->handle, "[:%08x] ",source);                fwrite(msg, sz , 1, inst->handle);                fprintf(inst->handle, "\n");                fflush(inst->handle);                break;        }        return 0;}

Because the type of the message package sent by skynet_error is PTYPE_TEXT, the source address and data of the message package are written into the file handle together. After skynet_context_new successfully starts a service, skynet_error (ctx, "LAUNCH % s", name, param? Param: ""), so there is a classic skynet startup screen.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.