Пример #1
0
/**
 * [ReactorThread] dispatch request to worker
 */
int swFactoryProcess_dispatch(swFactory *factory, swDispatchData *task)
{
    uint32_t schedule_key;
    uint32_t send_len = sizeof(task->data.info) + task->data.info.len;
    uint16_t target_worker_id;
    swServer *serv = SwooleG.serv;

    if (task->target_worker_id < 0)
    {
        //udp use remote port
        if (task->data.info.type == SW_EVENT_UDP || task->data.info.type == SW_EVENT_UDP6
                || task->data.info.type == SW_EVENT_UNIX_DGRAM)
        {
            schedule_key = task->data.info.from_id;
        }
        else
        {
            schedule_key = task->data.info.fd;
        }

#ifndef SW_USE_RINGBUFFER
        if (SwooleTG.factory_lock_target)
        {
            if (SwooleTG.factory_target_worker < 0)
            {
                target_worker_id = swServer_worker_schedule(serv, schedule_key);
                SwooleTG.factory_target_worker = target_worker_id;
            }
            else
            {
                target_worker_id = SwooleTG.factory_target_worker;
            }
        }
        else
#endif
        {
            target_worker_id = swServer_worker_schedule(serv, schedule_key);
        }
    }
    else
    {
        target_worker_id = task->target_worker_id;
    }

    if (SwooleTG.type == SW_THREAD_REACTOR)
    {
        return swReactorThread_send2worker((void *) &(task->data), send_len, target_worker_id);
    }
    else
    {
        swTrace("dispatch to worker#%d", target_worker_id);
        return swServer_send2worker_blocking(serv, (void *) &(task->data), send_len, target_worker_id);
    }
}
Пример #2
0
/**
 * Send the task result to worker
 */
int swTaskWorker_finish(swServer *serv, char *data, int data_len)
{
    swEventData buf;
    if (SwooleG.task_worker_num < 1)
    {
        swWarn("cannot use task/finish, because no set serv->task_worker_num.");
        return SW_ERR;
    }

    int ret;
    //for swoole_server_task
    if (current_task->info.type == SW_TASK_NONBLOCK)
    {
        buf.info.type = SW_EVENT_FINISH;
        buf.info.fd = current_task->info.fd;

        //write to file
        if (data_len >= sizeof(buf.data))
        {
            if (swTaskWorker_large_pack(&buf, data, data_len) < 0 )
            {
                swWarn("large task pack failed()");
                return SW_ERR;
            }
        }
        else
        {
            memcpy(buf.data, data, data_len);
            buf.info.len = data_len;
            buf.info.from_fd = 0;
        }

        //tasking

        /**
         * TODO: 这里需要重构,改成统一的模式
         */
        if (serv->factory_mode == SW_MODE_PROCESS)
        {
            ret = swServer_send2worker_blocking(serv, &buf, sizeof(buf.info) + buf.info.len, current_task->info.from_id);
        }
        else
        {
            ret = swWrite(SwooleG.event_workers->workers[current_task->info.from_id].pipe_worker, &buf, sizeof(buf.info) + data_len);
        }
    }
    else
    {
        uint64_t flag = 1;
        uint16_t worker_id = current_task->info.from_id;

        /**
         * Use worker shm store the result
         */
        swEventData *result = &(SwooleG.task_result[worker_id]);
        swPipe *task_notify_pipe = &(SwooleG.task_notify[worker_id]);

        result->info.type = SW_EVENT_FINISH;
        result->info.fd = current_task->info.fd;

        if (data_len >= sizeof(buf.data))
        {
            if (swTaskWorker_large_pack(result, data, data_len) < 0)
            {
                swWarn("large task pack failed()");
                return SW_ERR;
            }
        }
        else
        {
            memcpy(result->data, data, data_len);
            result->info.len = data_len;
            result->info.from_fd = 0;
        }

        while (1)
        {
            ret = task_notify_pipe->write(task_notify_pipe, &flag, sizeof(flag));
            if (ret < 0 && errno == EAGAIN)
            {
                if (swSocket_wait(task_notify_pipe->getFd(task_notify_pipe, 1), -1, SW_EVENT_WRITE) == 0)
                {
                    continue;
                }
            }
            break;
        }
    }
    if (ret < 0)
    {
        swWarn("TaskWorker: send result to worker failed. Error: %s[%d]", strerror(errno), errno);
    }
    return ret;
}