Opened 7 years ago

Closed 7 years ago

Last modified 7 years ago

#1483 closed enhancement (fixed)

Allow web service request to be blocking

Reported by: pett Owned by: Conrad Huang
Priority: blocker Milestone: 1.0
Component: Infrastructure Version:
Keywords: Cc:
Blocked By: Blocking:
Notify when closed: Platform: all
Project: ChimeraX

Description

Commands that invoke web services may well not want to return until the web service completes, therefore it would be good if the launch() method could optionally be blocking and not just non-blocking.

Change History (4)

comment:1 by Conrad Huang, 7 years ago

Milestone: 0.91.0

Example use case: realigning sequences. The job is short so a simple API would be nice.

Currently, Job is subclassed from Task, which always runs in a thread. A blocking job should not be run in a thread, and therefore should not derive from Task.

Move milestone to 1.0 because this will not be used by 0.9 features.

comment:2 by pett, 7 years ago

Okay, working on the Modeller tool refreshed my memory (since the command has a "block" option): running a command script typically needs to block until the command finishes.

Still could be milestoned to 1.0 though methinks.

comment:3 by Conrad Huang, 7 years ago

Resolution: fixed
Status: assignedclosed

Fixed in 3bad659e3.

Added blocking keyword to start() method for core.tasks.Task (which is inherited by core.tasks.Job). Previously, start() always called its run() method in a separate thread. Now, if blocking is present and true, then run() is called in the current thread instead. Example of using blocking:

from chimerax.webservices.opal_job import OpalJob
import time

class CCDJob(OpalJob):

    OPAL_SERVICE = "CCDService"

    def __init__(self, session, name):
        self.ccd = None
        super().__init__(session)
        # Nonblocking
        self.start(self.OPAL_SERVICE, name, blocking=False)
        # Same as above
        #self.start(self.OPAL_SERVICE, name)
        # Blocking
        #self.start(self.OPAL_SERVICE, name, blocking=True)

    def on_finish(self):
        self.ccd = self.get_file("stdout.txt")
        print("finished", time.ctime())

arg = CCDJob(session, "ARG")
print("after", time.ctime(), arg)

In the cases where blocking is false, the "after" message is printed first; when blocking is true, the "after" message is printed last (and runs more quickly because of the way monitoring works).

comment:4 by pett, 7 years ago

Nice! I've added support for it to the "modeller comparative" command. It was a bit confusing in that even when I specified "blocking=True" it continued to be non-blocking until I re-installed core. Would have been handy if the job code had thrown an error when handed an unexpected keyword....

Note: See TracTickets for help on using tickets.