OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-cogserver / opencog / cogserver / server / RequestManager.h

112 lines · c ref:
/*
 * opencog/cogserver/server/RequestManager.h
 *
 * Copyright (C) 2002-2007 Novamente LLC
 * Copyright (C) 2008 by OpenCog Foundation
 * Written by Andre Senna <senna@vettalabs.com>
 *            Gustavo Gama <gama@vettalabs.com>
 *
 * SPDX-License-Identifier: AGPL-3.0-or-later
 *
 * The Cogserver Request system is deprecated; users are encouraged to
 * explore writing guile (scheme) or python modules instead.
 */

#ifndef _OPENCOG_REQUEST_MANAGER_H
#define _OPENCOG_REQUEST_MANAGER_H

#include <mutex>
#include <vector>

#include <opencog/util/concurrent_queue.h>
#include <opencog/cogserver/server/Factory.h>
#include <opencog/cogserver/server/Request.h>
#include <opencog/cogserver/server/RequestClassInfo.h>

namespace opencog
{
/** \addtogroup grp_server
 *  @{
 */

/**
 * Request management uses the Registry base template, specialized
 * with the Request base class. The functionalities provided are:
 *   1. register, unregister and list request classes;
 *   2. create requests instances;
 *   3. push/pop from requests queue.
 * The lifecycle of each Request is controlled by the server itself
 * (that why no "destroyRequest" is provided). The server destroys the
 * Request instance right after its execution. All requests are assumed
 * to run to completion in a small amount of time, so that they don't
 * block later requests.
 *
 * This constraint does not apply to the Python and Scheme shells:
 * Work there can run for unlimited amounts of time. All that happens
 * there is that the shell client is blocked, until the job finishes
 * or until they kill it.  The GenericShell suppoprts out-of-band
 * ctrl-C, so the user can always ctrl-C to kill an out-of-control
 * Scheme or Python job.
 */
class RequestManager
{
protected:
    std::map<const std::string, AbstractFactory<Request> const*>
        _factories;

    // Container used to store references to requests
    std::map<const std::string, Request*> requests;

    std::mutex processRequestsMutex;
    concurrent_queue<Request*> requestQueue;

public:

    /** RequestManager's constructor. */
    RequestManager(void);

    /** RequestManager's destructor. */
    ~RequestManager(void);

    /**** Request Registry API ****/
    /** Register a new request class/type. Takes the class id and a derived
     *  factory for this particular request type. (note: the caller owns the
     *  factory instance). */
    bool registerRequest(const std::string& id,
                         AbstractFactory<Request> const* factory);

    /** Unregister a request class/type. Takes the class' id. */
    bool unregisterRequest(const std::string& id);

    /** Returns a list with the ids of all the registered request classes. */
    std::list<const char*> requestIds(void) const;

    /** Creates and returns a new instance of a request of class 'id'. */
    Request* createRequest(const std::string& id, CogServer&);

    /** Returns the class metadata from request class 'id'. */
    const RequestClassInfo& requestInfo(const std::string& id) const;

    /**
     * Adds request to the end of the requests queue.
     * Caution: after this push, the request might be executed and
     * deleted in a different thread, and so it must NOT be referenced
     * after the push!
     */
    void pushRequest(Request* request) { requestQueue.push(request); }

    /** Removes and returns the first request from the requests queue. */
    Request* popRequest(void) { return requestQueue.value_pop(); }

    /** Returns the requests queue size. */
    int getRequestQueueSize(void) { return requestQueue.size(); }

    /** Force drain of all outstanding requests */
    void processRequests(void);
}; // class

/** @}*/
}  // namespace

#endif // _OPENCOG_REQUEST_MANAGER_H