Setting RCC Worker timeout as a run condition

It’s suggested on page 33 of the RCC Development Guide that a timeout can be used as a worker run condition, but I can’t seem to find anything to show/say how that’s actually done.
Don’t suppose anyone has got it to work that might be able to give me some pointers?

I made a project on my Gitlab here:

The following is what I’ve written in the README on that repository.


Using timeouts in OpenCPI RCC Workers

This project is provided to give an example of how to use a timeout to trigger
the run method of an RCC Worker.

Using this project

Simply:

  • Clone this repo somewhere (location is not relevant).
  • Make sure that your opencpi install is set up.
    • You must have already sourced cdk/opencpi-setup.sh.
    • If you haven’t done this, demo.sh will tell you and exit.
  • Execute demo.sh.
    • demo.sh will handle registration, building, and running the example.
git clone https://gitlab.com/dawalters/ocpi-examples-and-issues.git
cd ocpi-examples-and-issues/examples/dom.example.rcc_worker_timeout
./demo.sh

Writing your own timeout

To trigger a timeout you need to set a custom RunCondition.

You do this by creating a RunCondition and then calling setRunCondition
on this in an RCC Worker.

The best way of doing this (in my opinion) is:

  • Create the RunCondition in the worker constructor.

  • setRunCondition where appropriate.

    • If the timeout is static (determined by a constant, not writable or
      initial) this can be done in the constructor.
    • Otherwise, if it uses an initial or writable property to set the
      timeout, this needs to be after setTimeout is called. This means in
      the start method, or later.

A simple example using a property called timeout_us to set a timeout:

static OCPI::RCC::PortMask NO_PORTS[1] = {OCPI::RCC::RCC_NO_PORTS};
typedef uint32_t timeout_in_usecs_t;
constexpr static timeout_in_usecs_t DEFAULT_TIMEOUT = 1e6;
constexpr static bool ENABLE_TIMEOUT = true;

class TimeoutWorker : public TimeoutWorkerBase {

  OCPI::RCC::RunCondition _rc;

  public: TimeoutWorker()
    : _rc(NO_PORTS, DEFAULT_TIMEOUT, ENABLE_TIMEOUT) {
  }

  OCPI::RCC::RCCResult start() {
    this->_rc.setTimeout(this->properties().timeout_us);
    this->setRunCondition(&this->_rc);
    return OCPI::RCC::RCC_OK;
  }

  OCPI::RCC::RCCResult run(bool timedout) {
    if (!timedout and this->firstRun()) {
      this->log(7, "`run` method ran for the first time; not a timeout");
    } else if (!timedout) {
      return this->setError("`run` method ran, but didn't timeout");
    } else {
      this->log(7, "`run` method ran after a timeout");
    }
    return OCPI::RCC::RCC_OK;
  }

};

The worker timeout.rcc in this project implements the above, but also uses
std::chrono to print the actual amount of time it took for the timeout to
happen.

Note: The example above uses a pure timeout RunCondition. If there is a
requirement to execute off of a port condition as well as a timeout, then the
NO_PORTS part of the above would need changing. There are various examples of
setting up different port based RunConditions in the official documentation.

References

  • RCC Development Guide v2.4.6 (link is to latest)
    • Section 4.3.6: RunCondition
      • Page 31, Table 4, Row 3
        • This is the constructor I am using.
        • I think the way I am calling this constructor (making an array
          beforehand and passing it in) is the only way it can be called.
      • Page 32, Table 5, Row 4: setTimeout
      • Page 33
        • Most of the information you need is on this page. Admittedly, it
          is slightly difficult to see how to do a pure timeout.
          Specifically, Table 7 doesn’t show it as an option.
    • Section 4.3.8
      • Page 34: setRunCondition

Thanks Dom, that’s really helpful!

One thing to note that I didn’t mention is the RunCondition above is for a pure timeout worker.

If there is a need to fire the run method off of a port becoming available as well as a timeout, then you need to change the RunCondition constructor w.r.t. the list of ports argument.

There’s some examples of that more standard kind of RunCondition in the already referenced pages from the RCC guide.