I have got Sinatra/Rails app and an action which starts some long process.
Ordinary I make a queue for background jobs. But this case is too simple and background process starts very rarely, so queue is an overhead.
So how could I run background process without queue?
get "/build_logs/:project" do
LogBuilder.new(params[:project]).generate
"done"
end
I've tried to make it as a new Thread or Process fork, but it didn't help.
I have had success with this (simplified) in Sinatra:
get '/start_process'
##pid = Process.spawn('external_command_to_run')
end
This returns the Process ID, which you can use to terminate the process later if you need. Also, this is on Linux, it will not work on Windows.
Related
i try to start a process in the background which executes some code. When i start the process, my app freezes until the background task is done. Iam using SuckerPunch to work around exactly this freezing, however the app still waits for the process to end. Do i have the wrong expectations ? How can i solve it ?
app/controller/mycontroller:
MyJob.perform_async(data_array)
app/jobs/myjob:
class MyClass
include SuckerPunch::Job
workers 1
def perform(data)
my code which takes around 20sec to execute
end
end
As described here, Passenger will fork my process, and I'll need to revive my background thread. I do that, and it usually works, but sometimes my process gets terminated before my background thread is finished. All I'm doing on that background thread is queuing a bunch of data so I can send it more efficiently in a bigger chunk. I just asked a similar question, but I have a new idea: I'm wondering if I can register for a callback similar to this one:
PhusionPassenger.on_event(:starting_worker_process) do |forked|...
but instead of on the :starting_worker_process event, I want to get notified that my process is about to be terminated so I can quickly flush my buffer and get out. Is there such an event?
Kernel provides #at_exit which can be used for this.
at_exit do
# Cleanup
end
From Passenger's source code, looks like there is an event called :stopping_worker_process. I haven't not tested this though.
I'm updating some content in my app and I want that to finish up when the user switches out of the app. It seems like I have to stop my currently-running update and start another one in the applicationDidEnterBackground method. It would be much more convenient if I could mark some work as something I want to run in the background before that method is called.
Here's the scenario:
I'm trying to update content and start running a SQL update that takes a bit of time. (More than the five seconds you have to return from applicationDidEnterBackground.)
The user leaves the app. The current update is suspended, but I really want it to finish.
I can start a new update which picks up where the other left off, but if the user switches back into the app I have SQL-level concurrency issues.
Is the only option to break down the SQL queries to smaller batches so I can switch over cleanly in the applicationDidEnterBackground callback? It almost doubles the execution time. (I'm not worried about the OS killing my background task, resume is handled fine.)
Ideally I'd be able to have the existing work continue seamlessly in the background (at the pleasure of the OS), is that possible? Are there better options?
(I've read the Programming Guide's section on executing background tasks.)
You can continue to run your current threads. You don't have to stop any of them and start new one.
The only thing which you need to do, if to use beginBackgroundTaskWithExpirationHandler (as proxi mentioned) when you entering background and use endBackgroundTask when you are done. This method gives your application up to 10 minutes of execution. UI of your application won't be accessible (since a user switched to another app), but all threads of your app will continue to run. System will pause all threads when your will do endBackgroundTask or 10 minutes will expire.
I would organize it like this
Have you processing threads running
In applicationDidEnterBackground call beginBackgroundTaskWithExpirationHandler.
Save UIBackgroundTaskIdentifier somewhere accessbile.
At the end of your processing thread, check whether UIBackgroundTaskIdentifier isn't 0 and if it's not, call endBackgroundTask. Set UIBackgroundTaskIdentifier to zero.
If I understand right, you just have to wrap your long-running operation into beginBackgroundTaskWithExpirationHandler block. See the method's documentation for details on how to use it.
I am creating a user defined thread library. I use Round-Robin scheduling algorithm and use the context switching method. But, I am unable to know what to do when a thread finishes its execution before the allotted time slot. The program is getting terminated. I actually want to reschedule all the threads, by calling the schedule function when the current thread gets terminated.
I found two ways to overcome this problem.
By calling explicitly thread_exit function at the end of the function that is being executed by the current thread.
By changing the stack contents such that the thread_exit function gets executed after the current function gets terminated.
But I am unable to find how to apply these solutions....
Anybody out there... plz help me...
It sounds like you have a bit of a design flaw. If I'm understanding you correctly, you're trying to implement a solution where you have threads that can be allocated to perform some task and after the task is complete, the thread goes idle waiting for the next task.
If that's true, I think I would design something like a daemon process or service that manages a queue for tasks coming in, a pool of threads responsible for executing the tasks with a controller that listens for new tasks.
I have an issue of Time out error when i click on the Export to Excel link in my application, due to heavy db transactions.
I want to change this functionality to the background so that user able to move forward while background process runs.
I want when user clicks on Export to Excel link background/new thread process runs and an email is sent to the user with a link to download a file.
I want to know which is best way to achieve this Creating new thread or Background process?
Thanks in Advance
You may want to use https://github.com/defunkt/resque or https://github.com/collectiveidea/delayed_job.
You can also watch:
http://railscasts.com/episodes/271-resque
http://railscasts.com/episodes/171-delayed-job-revised
http://railscasts.com/episodes/171-delayed-job (old one of above but free - but it is worth to buy a subscription)
There are three types of messages queues,
No queues - a new thread / process will be triggered for background task, eg: spawn
Database driven - corresponding task will be stored in a table in the database and will be deleted automatically on completion, eg: backgroundrb, delayed job
Message queues - Stored jobs in memory, eg: starling
I haven't used resque, but heard that it is bit complicated to configure.
Apart from running tasks in background, if you want to run some repetitive task on regular intervals, you can go for backgroundrb. Otherwise delayed job will be right choice.