Sharetribe Version: 6.1.0 Environment: Ubuntu 14.04 The Problem After running bundle exec rake jobs:work This delay job would slowly take up all the memory the server have, and cause server down. I...
seen from United States
seen from Singapore

seen from Malaysia
seen from Germany

seen from T1
seen from United States
seen from Argentina
seen from T1
seen from Germany

seen from United States
seen from Malaysia
seen from T1
seen from United States
seen from China
seen from China
seen from United States

seen from United States

seen from United Kingdom

seen from United States
seen from China
Sharetribe Version: 6.1.0 Environment: Ubuntu 14.04 The Problem After running bundle exec rake jobs:work This delay job would slowly take up all the memory the server have, and cause server down. I...
I am using delayed_job and moved to a new beefier server. So now I would like to run parallel jobs, as now I have the POWER!, but am confused on whether delayed_job can run multiple parallel queue...
delayed_job_active_record - ActiveRecord backend integration for DelayedJob 3.0+
PostgreSQL 8.4 だと UPDATE のサブクエリが使えないのでノーマルな方法(ただし遅い)でジョブのロックをします。
Problems locking jobs
You can try using the legacy locking code. It is usually slower but works better for certain people.
Delayed::Backend::ActiveRecord.configuration.reserve_sql_strategy = :default_sql
Although #32 fixed issues with PostgreSQL it still does not work with PostgreSQL 8.4, which for example ships with RHEL 6. Error: $ rake jobs:work --trace [Worker(host:foo.localdomain pid:8232)] ...
brauliobo added a commit to CIRANDAS/noosfero-ecosol that referenced this issue on 1 Dec 2014 Downgrade delayed_job_active_record to version 0.3.3 to fix issue 33 … collectiveidea/delayed_job_active_record#33
Détourner DelayedJobs pour exécuter des tâches répétitives
À mesure que votre application se complexifie, le besoin d'exécuter des tâches répétitives finit toujours par se faire sentir. C'est généralement des besoins fonctionnels qui exigent ce genre de tâches (envoi de rapports périodiques, de rappels d'expiration prochaine, etc.) mais c'est souvent des soucis de performances qui mènent à effectuer des calculs et des traitements par lots périodiques.
En Ruby, DelayedJob est l'outil le plus populaire pour exécuter des tâches de fond. Nous verrons dans cet article comment l'exploiter au mieux pour programmer l'exécution de tâches répétitives.
Background tasks are hard
Break it down!
Wiser people have said - if you have a problem, break it down! If the problem is bigger, break it down further. This is true both philosophically and technologically.
I'll describe a technological incident here in the hope that it could help someone else as well (when they land in this tricky situation, and are looking for a quick resolution). We use delayed_job gem in our web apps for asynchronous processing. It has performed pretty well for us all this while, but one fine day it caved in. We had a barrage of jobs into the dealyed_job table, and the job processing daemons were just unbearably slow. The reason being that there were 600K jobs in the queue, and the rate at which dealyed_job daemons fire the mysql queries every 5 seconds was too much I/O for the database server. Soon the slow query logs were flooded with update queries. I tried building a few indexes to speed up some of those queries, but the improvements weren't significant enough. What now? I filed a bug on the github repo in hope of greater good for future users, but that wasn't sufficient enough. Those jobs in the queue were time sensitive in nature, and at the current speed would take days, if not weeks to clear out. We needed a quick fix now, and a long term fix (better solution as compared to delayed_job) later.
Solution (quick fix): I went back in time and realized that delayed_job had performed well for a few thousand jobs in the table. That's it - we needed to pause, and break it down a bit - in this case, the mysql table. So we copied all the data from delayed_jobs table to a new table (backlog_jobs) and cleared the original table (the delayed_job table from where the jobs are picked). Then we copied the first 5000 jobs from backlog_jobs to delayed_jobs and deleted them from backlog_jobs. They were processed pretty quickly in a matter of minutes. Wallah! This was it. Then we wrote a small cron than runs every 1 minute and checks the count of delayed_jobs table. If there are less than 100 rows, it repeats the process, i.e. copies the next batch of 5000 jobs, and deletes it from backup_jobs. This way I got back to the older performance levels. Below are some handy queries that you will find useful:
# To create a copy of table CREATE table backlog_jobs like delayed_jobs; INSERT into backlog_jobs (SELECT * from delayed_jobs); DELETE from delayed_jobs;
# To copy jobs in batches INSERT into delayed_jobs (SELECT * from backlog_jobs order by id asc limit 5000); DELETE from backlog_jobs order by id asc limit 5000;
So the next time you face database related issues, break it down a bit. That's what database partitioning is all about, and that is what everything finally comes down to ;)
Would like to hear what I may have done wrong to start with, and what I could have done better. Don't hesitate to teach me a lesson (pun intended)... :P Philosophically speaking, life is an eternal learning process ;)
Delayed Job the Java Way
On the Rails side, we all know Delayed::Job the (probably most popular) background job eater. We've learned how to run it rake jobs:work, live with it RAILS_ENV=production script/delayed_job start and sometimes even kill -S KILL it. The beauty of Delayed::Job comes from it's simplicity, the only nuisance being the need to manage a separate process that handles the jobs, besides just booting your application. So, let's suppose you've decided to go with JRuby on production. Sooner or later you'll discover that it's not going to be a simple interpreter switch, especially with workers such as Delayed::Job, as gems such as daemons do not play well on the Java side. You may even review all of the precious code, to make sure JRuby benefits from threadsafe! just to find out that you need to stick with the "old" Ruby to spawn a delayed daemon. Well, good news, it doesn't have to necessary be that way, after all:
"JRuby is like the Matrix, only there's no spoon or fork()."
Funny but actually true, the JVM was designed to abstract away (sometimes too much) from the OS. If you ask a Java developer to built an asynchronously worker that polls and executes new tasks as they arrive, he'll immediately write a sort of new Thread() { ... }.start() code (or he starts configuring JMS :)). The point is that Java is a notoriously Thread oriented platform. And while using JRuby on Rails you might take advantage of it while running (asynchronous) job workers. First thing you should understand is that there's a Servlet API that is the base of every Java web server you'll find (very similar to what Rack is for all Ruby servers these days). On top of it there's an adapter, most servlet containers use, when serving Rack based applications called jruby-rack. And at last, knowing all the pieces, there's jruby-rack-worker that takes some worker code and runs it in a separate thread along side your application serving requests. The only downside is that one needs to make sure the worker loop plays by the rules in a multi-thread environment. Luckily, this is fairly easy and already handled for Delayed::Job. Thus the one thing left is how to set it up, well it depends on your web server choice. You'll need to configure a listener to start the background thread when your application gets deployed, these things are usually configured in a deployment descriptor web.xml. Warbler might spill out one for you even if you do not assemble into an "universal" (.war) package. Then just add the following XML snippet to the bottom : embedGist('1056100.js'); You'll find out more in the project's README. Happy Delaying ... P.S. Just to prove a point, I've adapted Navvy as well.