@startuml
|RunJob|
start
|SetupJob|
:InitMsg();
:initialize term_wait condition; <<task>> <<#aqua>>
:initialize nextrun_ready condition; <<task>> <<#aqua>>
:CreateUniqueJobName(); <<procedure>>
:set job status to JS_Created;
:get db connection from pool;
:InitJcrJobRecord(); <<procedure>>
if (job has client) then (yes)
  :GetOrCreateClientRecord(); <<procedure>>
endif
:CreateJobRecord(); <<procedure>>
:set jcr->jobid from jcr->jr.jobid; <<task>>
:NewPlugins(); <<procedure>>
:DispatchNewPluginOptions(); <<procedure>>
:GeneratePluginEvent(bDirEventJobStart); <<procedure>>
if (JobReads && !jcr->res.read_storage_list) then (yes)
  :CopyRwstorage(); <<procedure>>
endif
partition "Type Specific Setup" {
  :lots of magic omitted here;
}
:GeneratePluginEvent(bDirEventJobInit); <<procedure>>
|RunJob|
if (success) then (yes)
  |JobqAdd|
  :increment jcr's use counter; <<task>>
  if (scheduled in the future) then (yes)
    :spawn waiter thread;
  else (no)
    if (job canceled) then (yes)
      :put on top of ready_jobs;
    else (no)
      :priority-aware insert to waiting_jobs;
    endif
    :StartServer(); <<procedure>>
    note
      this will spawn a new jobq_server
      thread each time it is called until
      the jobq's thread limit is reached.
    end note
  endif
  |RunJob|
  if (success) then (yes)
    :return jobid; <<#tomato>>
    note
      at this point the jcr is either
      somewhere in the job-queue or there
      is a thread running that will inject
      it at some point in the future.
    end note
    detach
  endif
endif
:return 0; <<#tomato>>
detach
@enduml
