Delayed execution of Python rule from another Python rule

71 views
Skip to first unread message

Tony Edgin

unread,
May 27, 2023, 1:21:21 PM5/27/23
to iRODS-Chat
Hi everyone.

Is it possible to call a Python rule from within a delayExec called by another Python rule?

For example.

I have the following rule that I want to execute the following rule asynchronously from pep_api_data_obj_put_post.

def bulk_checksum(DataPathList, RescHier, Callback):
    for dataPath in DataPathList:
        _checksum(dataPath, RescHier, Callback)

Here's my incorrect guess at an implementation of pep_api_data_obj_put_post.

def pep_api_bulk_data_obj_put_post(RuleArgs, Callback, Rei):
    bulkOpInp = RuleArgs[2]
    dataPaths = [
        bulkOpInp.attriArray.sqlResult[0].row(r)
        for r in range(bulkOpInp.attriArray.rowCnt)]
    cond = "<PLUSET>0s</PLUSET><EF>0s REPEAT 0 TIMES</EF>" \
        + "<INST_NAME>irods_rule_engine_plugin-python-instance</INST_NAME>"
    rule = "Callback.bulk_checksum({paths},'{hier}')".format(
        paths=dataPaths,
        hier=bulkOpInp.condInput['resc_hier'])
    Callback.delayExec(cond, rule, "")

If I run this, it tells me that the global name 'Callback' is undefined.  I can't figure out how to pass Callback to bulk_checksum.  Is it even possible to call a python function from a delayExec()?

Cheers,
Tony

Terrell Russell

unread,
May 27, 2023, 7:38:33 PM5/27/23
to irod...@googlegroups.com

--
--
The Integrated Rule-Oriented Data System (iRODS) - https://irods.org
 
iROD-Chat: http://groups.google.com/group/iROD-Chat
---
You received this message because you are subscribed to the Google Groups "iRODS-Chat" group.
To unsubscribe from this group and stop receiving emails from it, send an email to irod-chat+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/irod-chat/3f64b956-db0e-4f29-9c3d-9a9ef6c7f9f7n%40googlegroups.com.

Tony Edgin

unread,
May 27, 2023, 10:36:46 PM5/27/23
to irod...@googlegroups.com
Hi Terrell.

I don't think it's the same issue. I think this is a PEBKAC issue and not a bug,

I partially figured out my issue. In the delayed rule text, I reference the variable Callback. This variable must exist in the later rule engine process environment where the rule text is executed. It is not the Callback that is an input parameter to pep_api_bulk_data_obj_put_post in the process environment where delayExec is called, like I incorrectly assumed. It turns out that delayExec provides the variable callback (lowercase c) in the environment where the rule text is executed. Switching my delayed rule to use callback, i.e.

    rule = "callback.bulk_checksum({paths},'{hier}')".format(
        paths=dataPaths,
        hier=bulkOpInp.condInput['resc_hier'])

got me passed the global name not defined issue.

Now I get the following error plus a stack trace.

May 27 18:46:20 pid:30916 remote addresses: 172.16.6.36, ::1 ERROR: rsExecRuleExpression : -1828000, [-] /irods_plugin_source/irods_rule_engine_plugin-python.cxx:796:irods::error exec_rule_expression(irods::default_re_ctx &, const std::string &, msParamArray_t *, irods::callback) :  status [RULE_ENGINE_ERROR]  errno [] -- message [irods_rule_engine_plugin_python::irods::error exec_rule_expression(irods::default_re_ctx &, const std::string &, msParamArray_t *, irods::callback) Caught Python exception.
Traceback (most recent call last):
  File "<string>", line 2, in expressionFcn
RuntimeError: iRODS Exception:
    file: /irods_plugin_source/irods_rule_engine_plugin-python.hpp
    function: msParam_t (anonymous namespace)::msParam_from_object_impl(boost::python::object &)
    line: 121
    code: -66000 (SYS_NOT_SUPPORTED)
    message:
        Attempted to extract a boost::python::object containing a non-conforming type

I'm incorrectly serializing the array dataPaths in the delay rule text. How should I serialize an array of strings for a delayExec call?

Cheers,
Tony

mustafa dikmen

unread,
May 28, 2023, 7:00:22 AM5/28/23
to irod...@googlegroups.com
Hi Tony,

I had encountered a similar issue...I guess passing just a path string is working.

def bulk_checksum(DataPath, RescHier, Callback):
    print(DataPath, RescHier)

def pep_api_bulk_data_obj_put_post(RuleArgs, callback, Rei):

    bulkOpInp = RuleArgs[2]
    dataPaths = [
        bulkOpInp.attriArray.sqlResult[0].row(r)
        for r in range(bulkOpInp.attriArray.rowCnt)]
    cond = "<PLUSET>0s</PLUSET><EF>0s REPEAT 0 TIMES</EF>" \
        + "<INST_NAME>irods_rule_engine_plugin-python-instance</INST_NAME>"
    r = bulkOpInp.condInput['resc_hier']
    for path in dataPaths:
        callback.delayExec(cond,
                       "callback.bulk_checksum('{}', '{}')".format(path, r), ""
                       )


Regards,
Mustafa


Tony Edgin

unread,
May 28, 2023, 9:49:29 AM5/28/23
to irod...@googlegroups.com
Hi Mustafa.

Thanks for the suggestion. That works. I'll use that if it's not possible to pass an array or list through a delayExec call.

Cheers,
Tony

Reply all
Reply to author
Forward
0 new messages