Class sh::ui::web::WebServerEngineDispatcher

class sh::ui::web::WebServerEngineDispatcher : public QObject, public sh::ui::web::WebModule

The web serve engine dispatcher module, used in dispatcher mode for providing a portal url which starts Shallot instances on request and internally redirects to them.

Public Functions

WebServerEngineDispatcher()
~WebServerEngineDispatcher()
void stop()

Stops the dispatcher.

void setEngine(WebServerEngine *webserver)

Assigns this web module to a sh::ui::web::WebServerEngine. .

WebServerEngine *webserver()

Returns the sh::ui::web::WebServerEngine this web module is assigned to (may be nullptr).

Public Static Functions

WebMainWindow *handleDispatching(std::function<WebMainWindow*(QString dispatcherUrl, QByteArray wtoken)> createWndFct)

Handles dispatching and creates a new main window (in child processes) on demand via a given factory function.

void doInitialize()
void doShutdown()
bool executeCommand_byQObjectReflection(QObject *o, WebServerEngineRequest *request, QString command, QString justLeftside = QString())

Convenience function often used by executeCommand().

For a QObject, it searches there for a slot with the name cmd_{command}, with `’/’s replaced by’_’s (so, for the command”foo/get_bars”, it searches for slotcmd_foo_get_bars`). If it finds one, it gets executed (in a worker thread). The request is considered as handled, if so.

If there is such a slot, but with appended __M in name, it is called in main thread!

Return

If it handled (answered) the command.

Private Functions

bool compareHashRedirectorWebworkerUrl(QByteArray hash, QString url, QString wtoken)

Compares a hash for a redirector webworker url to other data.

WorkerProcess *spawnNewWorker(WebServerEngineRequest *request)

Spawns a new worker.

Does not execute any requests on it.

WorkerProcess *findWorkerForWtoken(QString wtoken)

Returns the worker for a wtoken.

QString wtokenFromRequestCookie(WebServerEngineRequest *request)

Returns the wtoken from a request (typically from cookie).

bool executeCommand(WebServerEngineRequest *request, QString command) override

Executes command as requested by the browser, if responsible.

Read parameters, check if this module is responsible for answering, and then write an answer with request.

Implementations often use executeCommand_byQObjectReflection() for convenience.

Return

If it handled (answered) the command.

bool rootCommand(WebServerEngineRequest *request, QString webadapter) override

Returns the root (‘index.html’) content. .

Private Members

std::shared_ptr<WebServerEngine> _webserver
QMutex _workersmutex
QHash<QString, WorkerProcess*> _workers
JanitorThread _janitor

Private Slots

void cmd__drop_worker__M(WebServerEngineRequest *request)
void cmd__set_last_user_activity(WebServerEngineRequest *request)
void cmd__set_prevent_close_message(WebServerEngineRequest *request)
void cmd__working_for(WebServerEngineRequest *request)

Private Static Functions

void start(QUrl &url)

Starts the dispatcher engine, accepting http connections and internally handling child processes.

QByteArray hashRedirectorWebworkerUrl(QString url, QString wtoken)

Compute a hash for a redirector webworker url.

Private Static Attributes

std::shared_ptr<WebServerEngineDispatcher> _dispatcher = nullptr
QString _dispatcherId = QString::fromLatin1(sh::tools::Misc::generateUniqueHash())
QString _dispatcherCookieName = QUrl::toPercentEncoding(QString("shallot_%1").arg(_dispatcherId).toLocal8Bit())
class JanitorThread : public QThread

Public Functions

JanitorThread(WebServerEngineDispatcher *dispatcher)
void run() override

Private Functions

qint64 machineMemory()

Returns the amount of memory this machine provides (in bytes).

Returns -1 if this is not supported on the target platform or it failed.

void stopWorker(WorkerProcess *worker, QString reason)
int detectGoodMaxNumberWorkersByMachineCapabilities()
QList<WorkerProcess*> stopWorkers(QList<WorkerProcess*> workers, int stopcount, QString reason)

Private Members

WebServerEngineDispatcher *_dispatcher
double _allMemory
QHash<WorkerProcess*, double> _workerMemoryUsagesLastSeconds
class WorkerProcess : public QProcess

A internal Shallot worker process driving one Shallot session.

Public Functions

QByteArray wtoken()

The wtoken (used for association and security).

QUrl rootUrl()

The worker root url.

void request(WebServerEngineRequest *request)

Make a request to the worker.

qint64 workerPid()

Returns the process id of the worker.

qint64 memoryUsage()

Returns the current memory usage of this worker (in bytes).

Returns -1 if this is not supported on the target platform or it failed.

QDateTime lastBrowserHeartbeat()

Returns when a browser was seen connected to this worker last time.

QDateTime lastUserInteraction()

Returns when a user has interacted with this worker last time.

QString clientHost()

Returns the client host this worker is serving.

It’s not guaranteed to have some specific content (maybe an ip address), but is equal for the same host, some one can count how many hosts work for one particular client host.

QString preventCloseMessage()

Returns a reason message why this worker currently should not be closed (or "" if closing is fine).

See also isClosingInappropriate().

Note: This is reported asynchronously. You must not rely on its precise information, but solely use it for monitoring.

bool isClosingFine()

Returns if it is fine to stop this worker (or if there is a good reason to not do).

See also preventCloseMessage().

Note: This is reported asynchronously. You must not rely on its precise information, but solely use it for monitoring.

Private Functions

WorkerProcess(WebServerEngineDispatcher *dispatcher, QByteArray wtoken, QString clientHost, QStringList acceptedLanguages)
bool waitOnline()

Waits until the worker is online and ready for requests (or dead).

void initialize(QString rooturl, qint64 pid)

Initializes the worker instance (which exists on the dispatcher side!) by setting some final data.

void gotBrowserHeartbeat()

Refreshes the browser heartbeat timestamp.

See lastBrowserHeartbeat().

void gotUserInteraction(int value)

Refreshes the user interaction timestamp.

See lastUserInteraction().

void setPreventCloseMessage(QString message)

Sets the preventCloseMessage (empty: closeable).

Private Members

WebServerEngineDispatcher *_dispatcher
QByteArray _wtoken
QUrl _rooturl
QMutex _mutex
QWaitCondition _cnd_inited
qint64 _pid = -1
QDateTime _lastBrowserHeartbeat
QDateTime _lastUserInteraction
QString _clientHost
QString _preventCloseMessage
QRegularExpression _reProcStatus

Friends

friend class WebServerEngineDispatcher