示例#1
0
bool LocalForwarder::tryForward(Sirikata::Protocol::Object::ObjectMessage* msg) {
    ObjectConnection* conn = NULL;
    {
        boost::lock_guard<boost::mutex> lock(mMutex);

        // Destination connection must exist and be enabled
        ObjectConnectionMap::iterator it = mActiveConnections.find(msg->dest_object());
        if (it == mActiveConnections.end())
            return false;

        conn = it->second;

        // FIXME we can't sanity check here because we use this after
        // receiving from another space server (in which case we won't
        // have the source object...).
        // We only sanity check the source object when we're sure we're going to be able to
        // ship it.
        //ObjectConnectionMap::iterator src_it = mActiveConnections.find(msg->source_object());
        //if (src_it == mActiveConnections.end())
        //    return false;
    }

    assert(conn != NULL);

    // Finally, with all checks done, we can commit to doing local routing
    TIMESTAMP_START(tstamp, msg);
    TIMESTAMP_END(tstamp, Trace::FORWARDED_LOCALLY);

    // If a stop was requested, don't try to forward.
    if (mContext->stopped()) return false;

    bool send_success = conn->send(msg);
    if (!send_success) {
        TIMESTAMP_END(tstamp, Trace::DROPPED_AT_FORWARDED_LOCALLY);
        TRACE_DROP(DROPPED_AT_FORWARDED_LOCALLY);
        // FIXME do anything on failure?
        delete msg;
    }

    // At this point we've handled it, regardless of send's success
    return true;
}
示例#2
0
void SpaceNodeConnection::handleRead(const Chunk& chunk, const Sirikata::Network::Stream::PauseReceiveCallback& pause) {
    mHandleReadStage->started();

    // Parse
    ObjectMessage* msg = new ObjectMessage();
    bool parse_success = msg->ParseFromArray(&(*chunk.begin()), chunk.size());
    if (!parse_success) {
        LOG_INVALID_MESSAGE(session, error, chunk);
        delete msg;
        return;
    }

    TIMESTAMP_START(tstamp, msg);

    // Mark as received
    TIMESTAMP_END(tstamp, Trace::OH_NET_RECEIVED);

    // NOTE: We can't record drops here or we incur a lot of overhead in parsing...
    // Session messages need to be reliable, we force them through
    bool session_msg = (msg->dest_port() == OBJECT_PORT_SESSION);
    bool pushed = receive_queue.push(msg, session_msg);

    if (pushed) {
        // handleConnectionRead() could be called from any thread/strand. Everything that is not
        // thread safe that could result from a new message needs to happen in the main strand,
        // so just post the whole handler there.
        if (receive_queue.wentNonEmpty())
            mReceiveCB(this);
    }
    else {
        TIMESTAMP_END(tstamp, Trace::OH_DROPPED_AT_RECEIVE_QUEUE);
        TRACE_DROP(OH_DROPPED_AT_RECEIVE_QUEUE);
        delete msg;
    }

    mHandleReadStage->finished();

    // No matter what, we've "handled" the data, either for real or by dropping.
}
示例#3
0
bool SpaceNodeConnection::push(const ObjectMessage& msg) {
    TIMESTAMP_START(tstamp, (&msg));

    std::string data;
    msg.serialize(&data);

    // Try to push to the network
    bool success = socket->send(
        //Sirikata::MemoryReference(&(data[0]), data.size()),
        Sirikata::MemoryReference(data),
        Sirikata::Network::ReliableOrdered
                                );
    if (success) {
        TIMESTAMP_END(tstamp, Trace::OH_HIT_NETWORK);
    }
    else {
        TIMESTAMP_END(tstamp, Trace::OH_DROPPED_AT_SEND);
        TRACE_DROP(OH_DROPPED_AT_SEND);
    }

    return success;
}