some explanation of the diagram will arrive asap...
PostingJob are created and goes into the main thread event loop using mainly
NgPost::startPostingJob
They will go either in NgPost::_activeJob or in the queue NgPost::_pendingJobs (or NgPost::_packingJob cf dedicated section)
They are started (in main Thread, where they live) by emitting this signal:
void sigStartPosting(bool isActiveJob);
Here are its QueuedConnection connections:
connect(this, &PostingJob::sigStartPosting, this, &PostingJob::onStartPosting);
connect(this, &PostingJob::sigStopPosting, this, &PostingJob::onStopPosting);
connect(this, &PostingJob::sigPostingStarted, &_ngPost, &NgPost::onPostingJobStarted);
connect(this, &PostingJob::sigPackingDone, &_ngPost, &NgPost::onPackingDone);
connect(this, &PostingJob::sigPostingFinished, &_ngPost, &NgPost::onPostingJobFinished);
connect(this, &PostingJob::sigNoMorePostingConnection, &_ngPost, &NgPost::onNoMorePostingConnection);
PostingJob do its job by himself and signal
_ngPost when done.
It is using/holding mainly:
- PostingParamsPtr::_params
: all posting parameters including the list of files
- QFileInfoList::_files
: files that will be posted by _postFiles()
they can be directly _params->files()
if no packing (compression and/or par2)
most likely they will be replaced by the created archives located in _packingTmpDir
- QVector<NntpConnection *>::_nntpConnections and _closedConnections
: the independant NNTP connections (owning the TCP sockets)
- QQueue<NNTP::File *>::_filesToUpload
+ other QSet and current handle
: all NNTP::File are created at the beginning in _initPosting()
that fills _filesToUpload based on _files
(bare in mind that packing may have been done and _files updated)
Then the dequeue is all done by _readNextArticleIntoBufferPtr by _posters
(cf later...)
- QMutex::_secureDiskAccess
: reading from disk NNTP::Article needs to be Thread safe.
Idem for moving the NNTP::File from a Queue to another or the current handle.
- QVector<Poster *>::_posters
: Each poster will run 2 Threads:
- _builderThread for the ArticleBuilder (moveToThread
) where the NNTP::Article are prepared (yEnc encoded)
- _connectionsThread where its affected NntpConnection(s) live.
Poster(s) live in MainThread. They're aim is to have one independant Articles' builder
for a set of NntpConnection(s). One worker in its own thread with several consumers in another.
deleteLater
is used for both of them in order to destroy active objects in the thread where they live
(connection to QThread::finished())
Number of Threads, who lives where? external Process?
1.: MainThread where live:
NgPost, the
PostingJob(s) and their
Poster(s)
but also all
NNTP::File(s) and their
NNTP::Article(s)
2.: BuilderThread(s) and NntpThread(s) owned by
Poster(s) where
ArticleBuilder live in the first one
and the
NntpConnection(s) in the second.
3.: an extenal process is used asynchronously by
PostingJob(s) when required for packing.
Everything is happening in a non blocking architecture (sockets, processes, producers/consumers...)
Disk access is ¿safely? multithreaded if there are several
Posters.
Most Objects are independant:
- NntpConnection will handle the connection to the provider and then automatically post (consume)
NNTP::Article(s) until there are no more at which point it disconnects and signal it is IDLE.
- NNTP::Articles are owned (deleted) by their NNTP::File
who they send a signal when they are posted.
This way NNTP::File(s) knows when they are fully posted.
At this point they can flushed themselves in the nzb file and signal the PostingJob
who knows when all NNTP::File(s) are posted and thus when the job is done.