def __init__(self, flux_handle=None, path=".", handle=None): dest = RAW.flux_kvsdir_destroy super(KVSDir.InnerWrapper, self).__init__( ffi, lib, handle=handle, match=ffi.typeof("flux_kvsdir_t *"), prefixes=["flux_kvsdir_"], destructor=dest, ) if flux_handle is None and handle is None: # pragma: no cover raise ValueError( "flux_handle must be a valid Flux object or " "handle must be a valid kvsdir cdata pointer" ) if handle is None: directory = ffi.new("flux_kvsdir_t *[1]") future = RAW.flux_kvs_lookup( flux_handle, None, RAW.FLUX_KVS_READDIR, path ) RAW.flux_kvs_lookup_get_dir(future, directory) self.handle = RAW.flux_kvsdir_copy(directory[0]) RAW.flux_future_destroy(future) if self.handle is None or self.handle == ffi.NULL: raise EnvironmentError("No such file or directory")
def submit_get_id(future): if future is None or future == ffi.NULL: raise EnvironmentError(errno.EINVAL, "future must not be None/NULL") future.wait_for() # ensure the future is fulfilled jobid = ffi.new("flux_jobid_t[1]") RAW.submit_get_id(future, jobid) return int(jobid[0])
def id_parse(jobid_str): """ returns: An integer jobid :rtype int """ jobid = ffi.new("flux_jobid_t[1]") RAW.id_parse(jobid_str, jobid) return int(jobid[0])
def id_encode(jobid, encoding="f58"): """ returns: Jobid encoded in encoding :rtype str """ buflen = 128 buf = ffi.new("char[]", buflen) RAW.id_encode(int(jobid), encoding, buf, buflen) return ffi.string(buf, buflen).decode("utf-8")
def get_key_direct(flux_handle, key): valp = ffi.new("char *[1]") future = RAW.flux_kvs_lookup(flux_handle, None, 0, key) RAW.flux_kvs_lookup_get(future, valp) if valp[0] == ffi.NULL: return None ret = json.loads(ffi.string(valp[0]).decode("utf-8")) RAW.flux_future_destroy(future) return ret
def get_dict(self): """Get the raw "result" dictionary for the job Return the underlying "result" payload from ``flux_job_result(3)`` as a dictionary. """ result_str = ffi.new("char *[1]") RAW.result_get(self.handle, result_str) if result_str[0] == ffi.NULL: return None return json.loads(ffi.string(result_str[0]).decode("utf-8"))
def job_kvs_guest(flux_handle, jobid): """ :returns: The KVS guest directory of the given job :rtype: KVSDir """ path_len = 1024 buf = ffi.new("char[]", path_len) RAW.kvs_guest_key(buf, path_len, jobid, "") kvs_key = ffi.string(buf, path_len) return flux.kvs.get_dir(flux_handle, kvs_key)
def wait_get_status(future): """Get job status from a Future returned by job.wait_async() Process a response to a Flux job wait request. This method blocks until the response is received, then decodes the result to obtain the job status. :param future: a Flux future object returned by job.wait_async() :type future: Future :returns: job status, a tuple of: Job ID (int), success (bool), and an error (string) if success=False :rtype: tuple """ if future is None or future == ffi.NULL: raise EnvironmentError(errno.EINVAL, "future must not be None/NULL") future.wait_for() # ensure the future is fulfilled success = ffi.new("bool[1]") errstr = ffi.new("const char *[1]") jobid = ffi.new("flux_jobid_t[1]") RAW.wait_get_id(future, jobid) RAW.wait_get_status(future, success, errstr) return JobWaitResult(int(jobid[0]), bool(success[0]), ffi.string(errstr[0]))
def watch_once(flux_handle, key): """ Watches the selected key until the next change, then returns the updated value of the key """ if isdir(flux_handle, key): directory = get_dir(flux_handle) # The wrapper automatically unpacks directory's handle RAW.flux_kvs_watch_once_dir(flux_handle, directory) return directory out_json_str = ffi.new("char *[1]") RAW.flux_kvs_watch_once(flux_handle, key, out_json_str) if out_json_str[0] == ffi.NULL: return None return json.loads(ffi.string(out_json_str[0]).decode("utf-8"))
def submit_get_id(future): """Get job ID from a Future returned by job.submit_async() Process a response to a Flux job submit request. This method blocks until the response is received, then decodes the result to obtain the assigned job ID. :param future: a Flux future object returned by job.submit_async() :type future: Future :returns: job ID :rtype: int """ if future is None or future == ffi.NULL: raise EnvironmentError(errno.EINVAL, "future must not be None/NULL") future.wait_for() # ensure the future is fulfilled jobid = ffi.new("flux_jobid_t[1]") RAW.submit_get_id(future, jobid) return int(jobid[0])
def kz_stream_handler(kz_handle, arg): del kz_handle # unused (stream, prefix, handle) = ffi.from_handle(arg) buf = ffi.new("char *[1]") while True: try: count = RAW.get(handle, buf) if count == 0: break if prefix is None: generic_write(stream, ffi.string(buf[0])) else: for _ in ffi.string(buf[0]).splitlines(True): generic_write(stream, prefix) generic_write(stream, ffi.string(buf[0])) except EnvironmentError as err: if err.errno == errno.EAGAIN: pass else: raise err
def get_event(self, autoreset=True): """ Return the next event from a JobEventWatchFuture, or None if the event stream has terminated. The future is auto-reset unless autoreset=False, so a subsequent call to get_event() will try to fetch the next event and thus may block. """ result = ffi.new("char *[1]") try: RAW.event_watch_get(self.pimpl, result) except OSError as exc: if exc.errno == errno.ENODATA: self.needs_cancel = False return None # re-raise all other exceptions raise event = EventLogEvent(ffi.string(result[0]).decode("utf-8")) if autoreset is True: self.reset() return event
def recv( self, type_mask=raw.FLUX_MSGTYPE_ANY, match_tag=raw.FLUX_MATCHTAG_NONE, topic_glob=None, flags=0, ): """ Receive a message, returns a flux.Message containing the result or None """ match = ffi.new( "struct flux_match *", { "typemask": type_mask, "matchtag": match_tag, "topic_glob": topic_glob if topic_glob is not None else ffi.NULL, }, ) handle = self.flux_recv(match[0], flags) if handle is not None: return Message(handle=handle) return None
def get_rank(self): rank = ffi.new("uint32_t [1]") self.flux_get_rank(rank) return rank[0]
def submit_get_id(future): jobid = ffi.new("flux_jobid_t[1]") RAW.submit_get_id(future, jobid) return int(jobid[0])
def query_jcb(flux_handle, jobid, key): jcb_str = ffi.new("char *[1]") RAW.query_jcb(flux_handle, jobid, key, jcb_str) if jcb_str[0] == ffi.NULL: return None return json.loads(ffi.string(jcb_str[0]).decode("utf-8"))