Emonhub - Reduce CPU usage

Hi All,

I was digging through emonhub code for an unrelated issue and found this in emonhub_setup.py

  # Check settings only once per second (could be extended if processing power is scarce)
        now = time.time()
        if now - self._settings_update_timestamp < 1:
            return
        # Update timestamp
        self._settings_update_timestamp = now

     #more code which reparses the config follows...

Looking deeper at the code it appears to re-read the config file every second and check for changes.
The comment at the top of emonhub_setup.py seems to confirm this:


The check_settings() method is run regularly as well. It checks the settings
and returns True is settings were changed.

On my pi-Zero-W emonhub takes around 12% cpu.
I changed the 1 second timeout above to 15 and emonhub dropped to circa 2% CPU.

If this does indeed reparse the config every second, I think we’d agree this is overkill and a significant saving could be made by optimising it.

Can someone more knowledgable than me verify this ?

If I’m correct, it is certainly worth changing (most people I believe would be happy to wait 30s or longer for a config change to take effect)

1 Like

Ideally it would be configurable, I’d suggest. On most platforms it wouldn’t matter.

I think most people would think it wasn’t working if they saved the change just after the 30 s refresh had happened.

I’m not sure everyone realises or knows when they need to restart and when they don’t. Personally I always restart just to be on the safe side.

Since “auto” has been around for a while, it will probably cause problems if it’s removed. But yes, it’s unnecessary - and could be removed completely provided everyone is told that it’s gone. I think complete removal is better than a possible 30 s wait - if you change it to that, you’ll get a stream of “It sometimes works and sometimes doesn’t” type of complaints.

What does “Save” do - apart from the obvious? Can the act of saving set a flag that would be very cheap to poll? In which case, 0.1 s would be feasible.

I’m an old Unix hand, and the way that signalling something had changed to a process (change debug level, reread config etc) was usually done by… sending it a signal via kill… e.g. kill -SIGHUP .

For me, rereading and parsing config file regularly isn’t efficient.
Most users expect to have to restart after changing config, and most do so anyway. I would doubt most people know about this feature.

Also, the emonhub.conf default file is fairly large as it has lots of examples of things that may or may not be used. All needs parsed. Every second. My own emonhub.conf is 391 lines, and most are used.

Yes, its not an issue on more powerful platforms, but even on my prod pi3B, I went from 7% to 1.2% usage. Those cycles would be better used somewhere else.

My vote is to remove this ‘feature’ and expect users should restart after making changes (at a time of their convenience).

The cost of an rpi4 adds to the cost of an emonpi by at least £40. If a pi-Zero-2 could do the same for £15, that’s a heck of a saving.
The Zero-2 has roughly the same compute and memory as a 2b, which is more than enough to run emoncms and the full LAMP stack. (My emonpi had a 2B in it for years).

Let the debate continue.

I’d agree. I was simply warning what I expect will happen if, as is usual round here, the change is done and nobody is told that there’s even been a change, let alone what it was.

Could the check just look at the last modified time of the config file?

Keep track of the last modified time of the file when the config was last read… if the modified time has changed, re-parse the file and update the “last parsed file modified timestamp” variable.

2 Likes

That sounds like a good scheme. Would you mind suggesting some code to do so?

Just pushed some changes that add an option to increase the reload interval.

@Greebo your suggestion might be better!

I think so too - surely there’s a OS API call to get the file details which include creation and modification times? Reading and parsing the file reads more like a sledgehammer & nut solution to me.

I didn’t say it was a good solution, just a solution. And this feature (reloading settings) has been here since it’s inception I think.

Interesting, but it still defaults to 1 second.
Could we put a less aggressive figure in as default ?

I’m still for stopping the behaviour altogether as I think it’s bad practice, and if we look at other projects (eg apache, dnsmasq… in fact most) the behaviour is not to reload unless told… and I’d argue that’s what users expect.

No, as this way it isn’t a breaking change.

Yep, the logic is fairly simple, the procedure calls are simple and I thought I could quickly chuck a suggested change together… but then I started trying to understand the construction of the existing code and it all got too much for the amount of time I had available to look at it.

I haven’t given up, but it might have to wait a few days until I can find sufficient time to focus on it.

1 Like

Probably - the ones who haven’t noticed that it reloads anyway. But for those that have and have come to rely on it, as Brian says it’s a breaking change, and we’re the ones who have to supply the answers on the forum.

Or maybe leave the default as-is but add a switch that allows you to change the behaviour to suite your needs?

I’m pretty sure I’ve used daemons that behave both ways (i.e. many need a SIGHUP or manual restart, while others auto-reload their configs upon change).

I’m struggling to recall an example of the latter, but I do remember that it even logs it with a friendly “config file changed, reloading”.

Linux offers an inotify facility for those that want to know when their config files have changed. I’m no python programmer but it looks like it’s supported there too: https://pypi.org/project/inotify/

1 Like

Which is exactly what I have done. It could wait 3 million seconds if you wanted!

I’ll say it again though, it has been like this forever, so is hardly something to afflict folk generally!

True Brian. However, it is using more CPU than it really needs to. And that uses Watts, and those Watts add up. The whole point of energy monitoring is to lower usage. How may Pi’s are running EmonCMS?
How many kWh’s per year does that at up to? Even if the default was changed to 5 seconds, the CPU usage would drop significantly and most users would be unaware of the wait time.

Yes, can’t argue with that :slight_smile: