Execution of rule took too long due to sleep()

I started my journey to migrate from jython to python (HABApp).

Within the first parts is a buffer for messages, which are stored in a StringItem in order to use the persistence capabilities with RestoreOnStartup.
This buffer uses two simple functions to add and to remove the messages. These operations are locked with Lock().acquire()/release() as they run independently of each other.
Between the update of the StringItem and the availability as a new value is a certain time delay. In jython I’ve solved this wit a time.sleep(2) before the release of the lock. This works without any remarkable problems. The code is in no cyclic routine.
After migrating the code, HABApp warns about too long execution, which fills the log with the list of calls.

Therefor I have a couple of questions:

  • is it possible to stop or reduce the output of these warnings about the execution time? Preferably just for this specific part of code?
  • is it wise to postpone the call of Lock.release() with a run.at()? What would be the best way to do so?
  • is there an alternative to the StringItem to use the persistence for the buffer? This could make all the above topics obsolete.
    def AddMessageToBuffer(self, NewMessage):
        '''
        Nachricht zum Buffer hinzufügen
        '''
        LOGGER = "AddMessageToBuffer"

        # Puffer wird hier bearbeitet - verriegeln
        self.BufferLock.acquire()

        try:

            # ggf. Puffer zurücksetzen

            Messages = self.BufferItem.value
            if Messages is None:
                Messages = ""

            if Messages == "NULL":
                Messages = ""

            self.log.info(LOGGER + "   old Buffer: {}".format(Messages))

            # Nachricht an Puffer anhängen
            # to be changed to use python concepts... 
            Messages = Messages + NewMessage                    # Nachricht
            Messages = Messages + "%&%"                         # Endemarkierung

            self.log.info(LOGGER + "   new Buffer: {}".format(Messages))

            # Puffer beschreiben
            self.BufferItem.oh_post_update(Messages)
            # verzögert. damit der String schon sicher intern verarbeitet ist
            sleep(2)

        except Exception as e:
            self.log.error(LOGGER + " Error catched: {}".format(e))
            self.log.info(LOGGER + " Message: {}".format(NewMessage))
        finally:
            # Puffer wieder freigeben
            self.BufferLock.release()

        # Bearbeitung der Nachricht anstoßen
        self.BufferScheduler()

        return

Why don’t you use the ValueUpdateEvent for the BufferItem to start processing?
Then you don’t need all this logic since it’s always triggered when you added/removed something.

As an alternative you can use the ItemWatch and trigger if the buffer item hast not received an update for x seconds. That way it’s debounced, too.

This whole construct is rather strange to be honest.

Maybe a deque is the more appropriate approach (But I am not sure since I don’t understand your use case)?
You could just serialize the deque contents on every change to the StringItem and on Startup restore the deque form the StringItem. That way it’s decoupled.

Thanks for your feedback and ideas. I’ll have a look at the different solutions.
It was really helpful to get a view from another angle, so I’m not stuck in the “Never change a working solution” mode. The original code is quite old and has already been migrated to jython, which was also a 1:1 migration.