views:

62

answers:

2

I have a django view function that calls another function if a condition is true, the function is called as a separate process, the view returns a status variable which shows if the function was called or not, the status is returned to a ajax click event assigned to a button.
The problem is that when the function 'do_work' is executed ajax success function isn't run until 'do_work' terminates.

view function /update/

if condition:
        p = Process(target=do_work, args(pack,))
        p.daemon = True
        p.start()
        success = "True"
else:
        success = "False"
print success
return HttpResponse(success)

Ajax call

 $('button.update').click(function() {
                id = $(this).attr('id');
                $.post("/update/", {
                pack : id,
                }, function(result){
                    alert(result);
                    });
                return false;
                });

the 'print success' gets executed right away in both cases, but the alert wont pop up until the function do_woks terminates

A: 

What do you need in this? Can you be a bit more specific? Of course your AJAX call will not show an alert until do_work terminates. That's how any web interaction takes place...

Be more specific -

  1. What are you doing?
  2. What does "do_work()" do (List the code)?
  3. Does do_work() work independently?
  4. Why do you need to run it as a separate process?

UPDATE: OK this is what might be happening. You spawn a process. The parent process does not wait for the child process to terminate. After the child gets spawned, the parent process continues with the execution. Try adding p.join() after p.start(). That should make the parent process wait until the child process terminates & execute the flow only once.

P.S: Still curious as to why you need to spawn a child process as part of normal runtime execution? Process creation is an overhead!

MovieYoda
Please read the question again. Especially the part where he says "`print success` gets executed right away in both cases".
Manoj Govindan
@Srikar: `That should make the parent process wait until the child process terminates i.e. the parent should return without waiting for the child to terminate.
Manoj Govindan
@Manoj Govindan: That's correct , I don't want to wait for the process to finish
John Retallack
@Manoj: That's violates some programming rules! Atleast as part of an update I would like to know if the update was a success or fail. What's the point otherwise?
MovieYoda
@Srikar: (1) Can you explain which "programming rules" are violated and why? (2) consider a situation where an user is trying to _start_ a task using a web UI. The task itself will take some time and deliver its output through some other means (say email). The user would like to know if the tast _started_ well.
Manoj Govindan
@john: If you don't want to wait for the process to finish (meybe because it takes lot of time), then you might want to rethink your design... Can you tell something more about what you are trying to do?
MovieYoda
@Manoj: I am surprised you didn't know this! Anyway - http://www.kmoser.com/articles/Good_Programming_Practices.php (9th point) It's not a rule perse, but good practice.
MovieYoda
@Srikar: the 9th point says "Check return values for error conditions <snip>". This applies to the _consumer_ code not the _server_ code. It says that the _caller_ of a function that has the potential to throw errors should check for those errors. Quote: _"Everywhere you call a function that can throw an error, you should add code to deal with that potential error"_. Furthermore I don't see the relevance here.
Manoj Govindan
+1  A: 

Although you see the printed message before you return HttpResponse(success), that return statement in itself can't asynchronously finish the response.

Presumably after that function returns, your web server is still waiting for something else to happen (such as for all child processes to terminate) before it finishes the response.

For asynchronous tasks in Django I highly recommend Celery.

Ben James
can't I run the function asynchronously somehow ? I think Celery is a bit too much for my needs
John Retallack
John, check out my updates. Might help...
MovieYoda