示例#1
0
void TileCache::notifyAndRemoveSubscribers(const TileDesc& tile)
{
    std::unique_lock<std::mutex> lock(_tilesBeingRenderedMutex);

    std::shared_ptr<TileBeingRendered> tileBeingRendered = findTileBeingRendered(tile);
    if (!tileBeingRendered)
        return;

    const std::string message = tile.serialize("tile");
    Log::debug("Sending tile message to subscribers: " + message);

    for (const auto& i: tileBeingRendered->_subscribers)
    {
        auto subscriber = i.lock();
        if (subscriber)
        {
            //FIXME: This is inefficient; should just send directly to each client (although that is risky as well!
            // Re-emit the tile command in the other thread(s) to re-check and hit
            // the cache. Construct the message from scratch to contain only the
            // mandatory parts of the message.
            subscriber->sendToInputQueue(message);
        }
    }

    forgetTileBeingRendered(tile);
}
示例#2
0
void TileCache::saveTileAndNotify(const TileDesc& tile, const char *data, const size_t size, const bool priority)
{
    std::unique_lock<std::mutex> lock(_tilesBeingRenderedMutex);

    std::shared_ptr<TileBeingRendered> tileBeingRendered = findTileBeingRendered(tile);
    if (!priority && tileBeingRendered && tileBeingRendered->getVersion() != tile.getVersion())
    {
        Log::trace() << "Skipping unexpected tile ver: " << tile.getVersion()
                     << ", waiting for ver " << tileBeingRendered->getVersion() << Log::end;
        return;
    }

    // Save to disk.
    const auto cachedName = (tileBeingRendered ? tileBeingRendered->getCacheName()
                                               : cacheFileName(tile));
    const auto fileName = _cacheDir + "/" + cachedName;
    Log::trace() << "Saving cache tile: " << fileName << Log::end;
    std::fstream outStream(fileName, std::ios::out);
    outStream.write(data, size);
    outStream.close();

    // Notify subscribers, if any.
    if (tileBeingRendered)
    {
        if (!tileBeingRendered->_subscribers.empty())
        {
            const std::string message = tile.serialize("tile");
            Log::debug("Sending tile message to subscribers: " + message);

            for (const auto& i: tileBeingRendered->_subscribers)
            {
                auto subscriber = i.lock();
                if (subscriber)
                {
                    //FIXME: This is inefficient; should just send directly to each client (although that is risky as well!
                    // Re-emit the tile command in the other thread(s) to re-check and hit
                    // the cache. Construct the message from scratch to contain only the
                    // mandatory parts of the message.
                    subscriber->sendToInputQueue(message);
                }
            }
        }

        // Remove subscriptions.
        if (tileBeingRendered->getVersion() == tile.getVersion())
        {
            Log::debug() << "STATISTICS: tile internal roundtrip "
                         << tileBeingRendered->getElapsedTimeMs() << " ms." << Log::end;
            _tilesBeingRendered.erase(cachedName);
        }
    }
}