Slurm pending jobs - slurm

i have a problem with slurm every job i execute keeps pending
and i dont know what to do (im new to the field)
scontrol: show job
JobId=484 JobName=Theileiria_project
UserId=dhamer(1037) GroupId=Bio-info(1001) MCS_label=N/A
Priority=4294901741 Nice=0 Account=(null) QOS=normal
JobState=PENDING Reason=BeginTime Dependency=(null)
Requeue=1 Restarts=481 BatchFlag=1 Reboot=0 ExitCode=0:0
RunTime=00:00:00 TimeLimit=01:00:00 TimeMin=N/A
SubmitTime=2022-04-19T08:47:58 EligibleTime=2022-04-19T08:49:59
AccrueTime=2022-04-19T08:49:59
StartTime=2022-04-19T08:49:59 EndTime=2022-04-19T09:49:59 Deadline=N/A
SuspendTime=None SecsPreSuspend=0 LastSchedEval=2022-04-19T08:47:58
Partition=defq AllocNode:Sid=omix:377206
ReqNodeList=(null) ExcNodeList=(null)
NodeList=(null)
BatchHost=omics001
NumNodes=1 NumCPUs=30 NumTasks=30 CPUs/Task=1 ReqB:S:C:T=0:0:*:*
TRES=cpu=30,mem=32G,node=1,billing=30
Socks/Node=* NtasksPerN:B:S:C=0:0:*:* CoreSpec=*
MinCPUsNode=1 MinMemoryNode=32G MinTmpDiskNode=0
Features=(null) DelayBoot=00:00:00
OverSubscribe=NO Contiguous=0 Licenses=(null) Network=(null)
Command=/home/dhamer/test.sh
WorkDir=/home/dhamer
StdErr=/home/dhamer/Theileiria_project.log
StdIn=/dev/null
StdOut=/home/dhamer/Theileiria_project.log
Power=

Reason=BeginTime in the scontrol output means (according to man squeue) that "The job's earliest start time has not yet been reached." This is usually because the queue is full, or your job has low priority in the queue.
I would check with your systems administrators or your HPC helpdesk.
By the way, the submission command in your comment doesn't match the scontrol output, since in the script you set the timelimit to 5 minutes, but the output indicates a timelimit of 1 hour.

Related

How to set APScheduler timezone and execute task through an hour range?

scheduler = BlockingScheduler(timezone='US/Eastern')
scheduler.add_job(get_scores, 'cron', day_of_week='mon-fri', hour='8-18', minute='*/15')
scheduler.start()
I need this code to execute every 15 minutes from 9am - 5pm M-F EST. But for some reason it is doing:
Next wakeup is due at 2021-07-22 08:00:00-04:00 (in 47626.905794 seconds)
Thanks in advance!
timezone needs to be in the add_job, like:
scheduler.add_job(get_si_data, trigger='cron', day_of_week='mon-fri', hour='8-18', minute='*/15', timezone='US/Eastern')

python muti process runs on processor each core ?

In the same time processor could only run one process,if one process take 10 seconds to finish work, double process finish the same work it will take 20 seconds( without IO wait).
But the following code when you run it confused me.
#!python3
import time
import os, sys
from threading import Thread
from multiprocessing import Process
import logging
logger = logging.getLogger('TIMER')
formatter = logging.Formatter('%(asctime)s %(msecs)03d : %(message)s')
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
# datefmt='%a, %d %b %Y %H:%M:%S'
)
ProcessNum = 1
def loop():
start =time.process_time()
mr = 300000000
pr = 0
for i in range(0,mr):
pr = i
end = time.process_time()
logger.warning('pid {} coast time: {}'.format(os.getpid(),str(end-start)[:5] ))
def muti_process():
for i in range(ProcessNum):
t = Process(target=loop)
t.start()
logger.warning('start.... muti_process')
def muti_threads():
for i in range(1):
t = Thread(target=loop)
t.start()
logger.warning('start.... muti_threads')
if __name__ == '__main__':
muti_process()
set ProcessNum = 1 run program you get
21:18:03,469 process.py[line:29] WARNING start.... muti_process
21:18:14,419 process.py[line:22] WARNING pid 3849 coast time: 10.89
set ProcessNum = 2 run program you get:
21:18:39,443 process.py[line:29] WARNING start.... muti_process
21:18:39,445 process.py[line:29] WARNING start.... muti_process
21:18:50,638 process.py[line:22] WARNING pid 3856 coast time: 11.14
21:18:50,644 process.py[line:22] WARNING pid 3857 coast time: 11.15
set ProcessNum = 3 run program you get:
21:19:01,319 process.py[line:29] WARNING start.... muti_process
21:19:01,321 process.py[line:29] WARNING start.... muti_process
21:19:01,324 process.py[line:29] WARNING start.... muti_process
21:19:17,286 process.py[line:22] WARNING pid 3864 coast time: 15.61
21:19:17,415 process.py[line:22] WARNING pid 3863 coast time: 15.78
21:19:17,466 process.py[line:22] WARNING pid 3862 coast time: 15.82
set ProcessNum = 4 run program you get:
21:19:28,140 process.py[line:29] WARNING start.... muti_process
21:19:28,143 process.py[line:29] WARNING start.... muti_process
21:19:28,147 process.py[line:29] WARNING start.... muti_process
21:19:28,157 process.py[line:29] WARNING start.... muti_process
21:19:48,927 process.py[line:22] WARNING pid 3867 coast time: 19.68
21:19:49,049 process.py[line:22] WARNING pid 3870 coast time: 19.68
21:19:49,085 process.py[line:22] WARNING pid 3869 coast time: 19.65
21:19:49,092 process.py[line:22] WARNING pid 3868 coast time: 19.64
ENV: osx Mojave ,CPU :2.7G core i5(double core)python: Python 3.7.1
When you run one process it take 10 seconds, when you run two processes it take 11 seconds .
The result looks like that the two processes runs on the same time , at each cpu core. why?
It sounds like you’re asking why it takes longer for more processes.
First of all, your workload is fixed for each process. Multiprocessing/multithreading is used to break big problems into smaller problems, and then running the solutions to those smaller problems on multiple contexts (processes or threads.) In your code, you’re not doing that; you’re looping up to mr=300000000 on all the processes. If you do it once on one process, it will take the same amount of time as it would if you were to do it 4 times on 4 different processes.
What’s contributing to the increase in time when you increase the number of processes is the fork() system call; this, on a Unix machine, is the call to create a new process. This call takes relatively a lot of time because it has to copy the parent process’ whole address space (memory for variables and such.)
Hope that answers your question!

Celery beat is not showing or executing scheduled tasks

I am using celery and celery beat to handle task execution and scheduled tasks in a Python project. I am not using django.
Execution of celery tasks is working as expected. However I have run into a wall trying to get scheduled tasks (celery beat) to run.
I have followed the celery documentation to add my task to app.conf.beat_schedule successfully. If I print out the beat schedule after adding my task, I can see that the task has been added to app.conf.beat_schedule successfully.
from celery import Celery
from celery.task import task
# Celery init
app = Celery('tasks', broker='pyamqp://guest#localhost//')
# get the latest device reading from the appropriate provider
#app.task(bind=True, retry_backoff=True)
def get_reading(self, provider, path, device, config, location, callback):
logger.info("get_reading() called")
module = importlib.import_module('modules.%s' % provider)
try:
module.get_reading(path, device, config, location, callback)
except Exception as e:
self.retry(exc=e)
# add the periodic task
def add_get_reading_periodic_task(provider, path, device, config, location, callback, interval = 600.0):
app.conf.beat_schedule = {
"poll-provider": {
"task": "get_reading",
"schedule": interval,
"args": (provider, path, device, config, location, callback)
}
}
logger.info(app.conf.beat_schedule)
logger.info("Added task 'poll-provider' for %s to beat schedule" % provider)
Looking at my application log, I can see that app.conf.beat_schedule has been updated with the data passed to add_get_reading_periodic_task():
2017-08-17 11:07:13,216 - gateway - INFO - {'poll-provider': {'task': 'get_reading', 'schedule': 10, 'args': ('provider1', '/opt/provider1', None, {'location': {'lan.local': {'uri': 'http://192.168.1.10'}}}, 'lan.local', {'url': 'http://localhost:8080', 'token': '*******'})}}
2017-08-17 11:07:13,216 - gateway - INFO - Added task 'poll-provider' for provider1 to beat schedule
I'm manually running celery worker and celery beat simultaneously (in different terminal windows) on the same application file:
$ celery worker -A gateway --loglevel=INFO
$ celery beat -A gateway --loglevel=DEBUG
If I call get_reading.delay(...) within my application, it is executed by the celery worker as expected.
However, the celery beat process never shows any indication that the scheduled task is registered:
celery beat v4.0.2 (latentcall) is starting.
__ - ... __ - _
LocalTime -> 2017-08-17 11:05:15
Configuration ->
. broker -> amqp://guest:**#localhost:5672//
. loader -> celery.loaders.app.AppLoader
. scheduler -> celery.beat.PersistentScheduler
. db -> celerybeat-schedule
. logfile -> [stderr]#%DEBUG
. maxinterval -> 5.00 minutes (300s)
[2017-08-17 11:05:15,228: DEBUG/MainProcess] Setting default socket timeout to 30
[2017-08-17 11:05:15,228: INFO/MainProcess] beat: Starting...
[2017-08-17 11:05:15,248: DEBUG/MainProcess] Current schedule:
<ScheduleEntry: celery.backend_cleanup celery.backend_cleanup() <crontab: 0 4 * * * (m/h/d/dM/MY)>
[2017-08-17 11:05:15,248: DEBUG/MainProcess] beat: Ticking with max interval->5.00 minutes
[2017-08-17 11:05:15,250: DEBUG/MainProcess] beat: Waking up in 5.00 minutes.
[2017-08-17 11:10:15,351: DEBUG/MainProcess] beat: Synchronizing schedule...
[2017-08-17 11:10:15,355: DEBUG/MainProcess] beat: Waking up in 5.00 minutes.
[2017-08-17 11:15:15,400: DEBUG/MainProcess] beat: Synchronizing schedule...
[2017-08-17 11:15:15,402: DEBUG/MainProcess] beat: Waking up in 5.00 minutes.
[2017-08-17 11:20:15,502: DEBUG/MainProcess] beat: Synchronizing schedule...
[2017-08-17 11:20:15,504: DEBUG/MainProcess] beat: Waking up in 5.00 minutes.
This is seemingly confirmed by running celery inspect scheduled:
-> celery#localhost.lan: OK
- empty -
I have tried starting celery beat both before and after adding the scheduled task to app.conf.beat_schedule, and in both cases the scheduled task never appears in celery beat.
I read that celery beat did not support dynamic reloading of the configuration until version 4, but I am running celery beat 4.0.2
What am I doing wrong here? Why isn't celery beat showing my scheduled task?
Have you tried using the code as described in the Documentation:
#app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
# Calls test('hello') every 10 seconds.
sender.add_periodic_task(10.0, test.s('hello'), name='add every 10')
?
create a model for creating periodic tasks:
class TaskScheduler(models.Model):
periodic_task = models.OneToOneField(
PeriodicTask, on_delete=models.CASCADE, blank=True, null=True)
node = models.OneToOneField(
Node, on_delete=models.CASCADE, blank=True, null=True)
#staticmethod
def schedule_every(task_name, period, every, sheduler_name, args, queue=None):
# schedules a task by name every "every" "period". So an example call would be:
# TaskScheduler('mycustomtask', 'seconds', 30, [1,2,3])
# that would schedule your custom task to run every 30 seconds with the arguments 1,2 and 3 passed to the actual task.
permissible_periods = ['days', 'hours', 'minutes', 'seconds']
if period not in permissible_periods:
raise Exception('Invalid period specified')
# create the periodic task and the interval
# create some name for the period task
ptask_name = sheduler_name
interval_schedules = IntervalSchedule.objects.filter(
period=period, every=every)
if interval_schedules: # just check if interval schedules exist like that already and reuse em
interval_schedule = interval_schedules[0]
else: # create a brand new interval schedule
interval_schedule = IntervalSchedule()
interval_schedule.every = every # should check to make sure this is a positive int
interval_schedule.period = period
interval_schedule.save()
if(queue):
ptask = PeriodicTask(name=ptask_name, task=task_name,
interval=interval_schedule, queue=queue)
else:
ptask = PeriodicTask(name=ptask_name, task=task_name,
interval=interval_schedule)
if(args):
ptask.args = args
ptask.save()
return TaskScheduler.objects.create(periodic_task=ptask)
#staticmethod
def schedule_cron(task_name, at, sheduler_name, args):
# schedules a task by name every day at the #at time.
# create some name for the period task
ptask_name = sheduler_name
crons = CrontabSchedule.objects.filter(
hour=at.hour, minute=at.minute)
if crons: # just check if CrontabSchedule exist like that already and reuse em
cron = crons[0]
else: # create a brand new CrontabSchedule
cron = CrontabSchedule()
cron.hour = at.hour
cron.minute = at.minute
cron.save()
ptask = PeriodicTask(name=ptask_name,
crontab=cron, task=task_name)
if(args):
ptask.args = args
ptask.save()
return TaskScheduler.objects.create(periodic_task=ptask)
def stop(self):
""" pauses the task """
ptask = self.periodic_task
ptask.enabled = False
ptask.save()
def start(self):
ptask = self.periodic_task
ptask.enabled = True
ptask.save()
def terminate(self):
self.stop()
ptask = self.periodic_task
PeriodicTask.objects.get(name=ptask.name).delete()
self.delete()
ptask.delete()
and then from you code
# give the periodic task a unique name
scheduler_name = "%s_%s" % ('node_heartbeat', str(node.pk))
# organize the task arguments
args = json.dumps([node.extern_id, node.pk])
# create the periodic task in heartbeat queue
task_scheduler = TaskScheduler().schedule_every(
'core.tasks.pdb_heartbeat', 'seconds', 15, scheduler_name , args, 'heartbeat')
task_scheduler.node = node
task_scheduler.save()
the original class I came across here a long time ago I've added schedule_cron

SGE jobs terminating after 3 hours

I'm used to Torque so I'm hoping that some Sun SGE guru can help. I can't figure out why my jobs are terminating at, near as I can tell 3 hours. The jobs are being submitted to an empty queue with no competition on a new install of ROCKS 6.2. Jobs shorter than 3 hours do not have any problems.
Here's the Server configuration (I think)
[user#machine]$ qconf -ssconf
algorithm default
schedule_interval 0:0:05
maxujobs 0
queue_sort_method load
job_load_adjustments np_load_avg=0.50
load_adjustment_decay_time 0:10:30
load_formula slots
schedd_job_info false
flush_submit_sec 1
flush_finish_sec 10
params none
reprioritize_interval 0:0:0
halftime 168
usage_weight_list cpu=1.000000,mem=0.000000,io=0.000000
compensation_factor 5.000000
weight_user 0.250000
weight_project 0.250000
weight_department 0.250000
weight_job 0.250000
weight_tickets_functional 0
weight_tickets_share 0
share_override_tickets TRUE
share_functional_shares TRUE
max_functional_jobs_to_schedule 200
report_pjob_tickets TRUE
max_pending_tasks_per_job 50
halflife_decay_list none
policy_hierarchy OFS
weight_ticket 0.010000
weight_waiting_time 0.000000
weight_deadline 3600000.000000
weight_urgency 0.100000
weight_priority 1.000000
max_reservation 0
default_duration INFINITY
The queue configuration
[user#machine]$ qconf qconf -sql
all.q
[user#machine]$ qconf qconf -sq all.q
qname all.q
hostlist #allhosts
seq_no 0
load_thresholds np_load_avg=1.75
suspend_thresholds NONE
nsuspend 1
suspend_interval 00:05:00
priority 0
min_cpu_interval 00:05:00
processors UNDEFINED
qtype BATCH INTERACTIVE
ckpt_list NONE
pe_list make mpi mpich orte
rerun FALSE
slots 1,[compute-0-0.local=4],[compute-1-0.local=4], \
[compute-1-1.local=4],[compute-1-2.local=4], \
[compute-1-3.local=4],[compute-1-4.local=4], \
[compute-2-0.local=4],[compute-2-1.local=4], \
[compute-2-2.local=4],[compute-2-4.local=4]
tmpdir /tmp
shell /bin/bash
prolog NONE
epilog NONE
shell_start_mode posix_compliant
starter_method NONE
suspend_method NONE
resume_method NONE
terminate_method NONE
notify 00:00:60
owner_list NONE
user_lists NONE
xuser_lists NONE
subordinate_list NONE
complex_values NONE
projects NONE
xprojects NONE
calendar NONE
initial_state default
s_rt INFINITY
h_rt INFINITY
s_cpu INFINITY
h_cpu INFINITY
s_fsize INFINITY
h_fsize INFINITY
s_data INFINITY
h_data INFINITY
s_stack INFINITY
h_stack INFINITY
s_core INFINITY
h_core INFINITY
s_rss INFINITY
h_rss INFINITY
s_vmem INFINITY
h_vmem INFINITY
And here's a sample in progress job status.
[user#machine]$ qstat -j 255
==============================================================
job_number: 255
exec_file: job_scripts/255
submission_time: Mon Jul 3 11:19:07 2017
owner: <user>
uid: 500
group: <user>
gid: 502
sge_o_home: /home/<user>
sge_o_log_name: <user>
sge_o_path: /home/<user>/<programDIR>/bin/linux:/home/<user>/<gitRootDIR>/<codeDIR>/bin/linux:/opt/openmpi/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/java/latest/bin:/opt/maven/bin:/opt/rocks/bin:/opt/rocks/sbin:/opt/gridengine/bin/linux-x64:/home/<user>/scripts/:/home/<user>/bin
sge_o_shell: /bin/bash
sge_o_workdir: <CORRECT working DIR>
sge_o_host: <HOSTNAME>
account: sge
merge: y
mail_options: ae
mail_list: <user#domain.tld>
notify: FALSE
job_name: STDIN
stdout_path_list: NONE:NONE:test3_w5.eo
jobshare: 0
env_list: HOSTNAME=<HOSTNAME>.FQDN,SHELL=/bin/bash,TERM=xterm,HISTSIZE=1000,EGS_HOME=/home/<user>/<programDIR>/,SSH_CLIENT=172.24.56.106 56512 22,SGE_ARCH=linux-x64,SGE_CELL=default,MPICH_PROCESS_GROUP=no,QTDIR=/usr/lib64/qt-3.3,QTINC=/usr/lib64/qt-3.3/include,SSH_TTY=/dev/pts/0,ROCKSROOT=/opt/rocks/share/devel,ANT_HOME=/opt/rocks,USER=<user>,LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:,LD_LIBRARY_PATH=/opt/gridengine/lib/linux-x64:/opt/openmpi/lib,ROCKS_ROOT=/opt/rocks,<DEFAULT_BATCH_SYSTEM>=sge,PATH=/home/<user>/<programDIR>/bin/linux:/home/<user>/<gitRootDIR>/<codeDIR>/bin/linux:/opt/openmpi/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/java/latest/bin:/opt/maven/bin:/opt/rocks/bin:/opt/rocks/sbin:/opt/gridengine/bin/linux-x64:/home/<user>/scripts/:/home/<user>/bin,MAIL=/var/spool/mail/<user>,MAVEN_HOME=/opt/maven,<codeDIR>=/home/<user>/<gitRootDIR>/<codeDIR>/,PWD=/home/<user>/<programDIR>/dosxyznrc,JAVA_HOME=/usr/java/latest,_LMFILES_=/usr/share/Modules/modulefiles/rocks-openmpi,SGE_EXECD_PORT=537,LANG=en_US.iso885915,MODULEPATH=/usr/share/Modules/modulefiles:/etc/modulefiles,SGE_QMASTER_PORT=536,LOADEDMODULES=rocks-openmpi,SGE_ROOT=/opt/gridengine,HISTCONTROL=ignoredups,SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass,HOME=/home/<user>,SHLVL=2,ROLLSROOT=/opt/rocks/share/devel/src/roll,MPIHOME=/opt/openmpi,LOGNAME=<user>,CVS_RSH=ssh,QTLIB=/usr/lib64/qt-3.3/lib,SSH_CONNECTION=172.24.56.106 56512 172.24.59.111 22,MODULESHOME=/usr/share/Modules,LESSOPEN=||/usr/bin/lesspipe.sh %s,OMEGA_HOME=/home/<user>/<gitRootDIR>/<codeDIR>/omega,EGS_CONFIG=/home/<user>/<gitRootDIR>/<codeDIR>/specs/linux.conf,G_BROKEN_FILENAMES=1,OMPI_MCA_btl=self,sm,tcp,BASH_FUNC_module()=() { eval `/usr/bin/modulecmd bash $*`
},_=/opt/gridengine/bin/linux-x64/qsub
script_file: STDIN
usage 1: cpu=00:13:50, mem=833.52093 GBs, io=0.05473, vmem=1.109G, maxvmem=1.109G
scheduling info: (Collecting of scheduler job information is turned off)
It sounds like the complex has a default run time. You can inspect these w/:
qconf -sc | grep -e '^#' -e _rt
If the default is not 0:0:0, then that value is enforced on the run time.
You can override this default w/:
qsub -l s_rt=8:0:0 ...
for 8 hours, for example. Set s_rt or h_rt (soft/hard limits) based on which is set at the complex level.

Is it possible to do simple edits to transform a black and white SVG to a grayscale one?

I am using mscgen to create an image for documentation purposes of a complex set of events for one of my tools.
I put that image on my website (bottom of that page) and the problem is that the lines tend to disappear when resized to a scale that fits the page. (Update: the answer by Sander fixed the problem, there is a PNG screenshot of what I was seeing, you may want to enlarge it to see at 1:1 scale.)
I am thinking that if it were marked as a grayscale image, instead of black and white, then the scaling may work better. Is that at all possible?
Unfortunately Stackoverflow does not let me upload an SVG image... I can put part of the source if requested. You may find the source by following the link (see above.) However, there my msc code and you can recreate the SVG image with the following command:
mscgen -T svg -o snapinit.svg snapinit.msc
The input code (snapinit.msc):
msc {
hscale = "2";
a [label="snapinit"],
b [label="snapcommunicator"],
c [label="snapserver"],
d [label="snapbackend (permanent)"],
e [label="snapbackend (cron)"],
f [label="neighbors"],
g [label="snapsignal"];
d note d [label="images, page_list, sendmail,snapwatchdog"];
#
# snapinit initialization
#
a=>a [label="init()"];
a=>a [label="--detach (optional)"];
|||;
... [label="pause (0 seconds)"];
|||;
a=>>a [label="connection timeout"];
a=>b [label="start (fork+execv)"];
|||;
b>>a;
#
# snapcommunicator initialization
#
b=>b [label="open socket to neighbor"];
b->f [label="CONNECT type=frontend ..."];
f->b [label="ACCEPT type=backend ..."];
... [label="or"];
f->b [label="REFUSE type=backend"];
|||;
... [label="neighbors may try to connect too"];
|||;
f=>f [label="open socket to neighbor"];
f->b [label="CONNECT type=backend ..."];
b->f [label="ACCEPT type=frontend ..."];
... [label="or"];
b->f [label="REFUSE type=frontend"];
#
# snapinit registers with snapcommunicator
#
|||;
... [label="pause (10 seconds)"];
|||;
a=>a [label="open socket to snapcommunicator"];
a->b [label="REGISTER service=snapinit;version=<version>"];
b->a [label="READY"];
a->b [label="SERVICES list=...depends on snapinit.xml..."];
a=>a [label="wakeup services"];
|||;
b->a [label="HELP"];
a->b [label="COMMANDS list=HELP,QUITTING,READY,STOP"];
#
# snapinit starts snapserver which registers with snapcommunicator
#
|||;
... [label="pause (0 seconds)"];
|||;
--- [label="...start snapserver..."];
a=>>a [label="connection timeout"];
a=>c [label="start (fork+execv)"];
c>>a;
c=>c [label="open socket to snapcommunicator"];
c->b [label="REGISTER service=snapserver;version=<version>"];
b->c [label="READY"];
#
# snapinit starts various backends (images, sendmail, ...)
#
|||;
... [label="pause (<wait> seconds, at least 1 second)"];
|||;
--- [label="...(start repeat for each backend)..."];
a=>>a [label="connection timeout"];
a=>d [label="start (fork+execv)"];
d>>a;
d=>d [label="open socket to snapcommunicator"];
d->b [label="REGISTER service=<service name>;version=<version>"];
b->d [label="READY"];
b->d [label="STATUS service=snapwatchdog"];
|||;
... [label="pause (<wait> seconds, at least 1 second)"];
|||;
--- [label="...(end repeat)..."];
#
# snapinit starts snapback (CRON task)
#
|||;
... [label="...cron task, run once per timer tick event..."];
|||;
a=>>a [label="CRON timer tick"];
a=>a [label="if CRON tasks still running, return immediately"];
a=>e [label="start (fork+execv)"];
e>>a;
e=>e [label="open socket to snapcommunicator"];
e->b [label="REGISTER service=snapbackend;version=<version>"];
b->e [label="READY"];
|||;
e=>>e [label="run CRON task 1"];
e=>>e [label="run CRON task 2"];
...;
e=>>e [label="run CRON task n"];
|||;
e->b [label="UNREGISTER service=snapbackend"];
|||;
... [label="...(end of cron task)..."];
#
# STOP process
#
|||;
--- [label="snapinit STOP process with: 'snapinit stop' or 'snapsignal snapinit/STOP'"];
|||;
g->b [label="'snapsignal snapinit/STOP' command sends STOP to snapcommunicator"];
b->a [label="STOP"];
... [label="...or..."];
a->a [label="'snapinit stop' command sends STOP to snapinit"];
...;
a->b [label="UNREGISTER service=snapinit"];
a->b [label="STOP"];
b->c [label="snapserver/STOP"];
b->d [label="<service name>/STOP"];
b->e [label="snapbackend/STOP"];
c->b [label="UNREGISTER service=snapserver"];
c->c [label="exit(0)"];
d->b [label="UNREGISTER service=<service name>"];
d->d [label="exit(0)"];
e->b [label="UNREGISTER service=snapbackend (if still running at the time)"];
e->e [label="exit(0)"];
... [label="once all services are unregistered"];
b->f [label="DISCONNECT"];
}
Remove the shape-rendering="crispEdges" attribute from the svg tag (line 6 in your svg)
Browsers usually switch off anti-aliasing when shape-rendering="crispEdges" - and that's what's needed in this situation.
Use an other value for shape-rendering (e.g. "auto" or "geometricPrecision") or - remove the attribute and you're set.
(Initially I thought that png's rendered by mscgen could relieve your sorrows as well, but while it looks ok in firefox & chrome, safari's rendition is less appealing)
Reference: The 'shape-rendering' property at w3.org

Resources