Last verteilen durch verzögertes Abarbeiten von Funktionen

Begonnen von FHEMAN, 18 Februar 2018, 02:00:08

Vorheriges Thema - Nächstes Thema

FHEMAN

Folgendes Problem:

Aufrufe, wie bspw. stündlich mehrere addLog (Plotabriss vermeiden) am Stück bringen mein System für wenige Sekunden zum stehen.
Da ich gerade dabei bin, meine Fhem Freezes zu minimieren, sah ich mich gezwungen, solche Aufrufe in mehreren ATs zu splitten. So dass Fhem quasi zwischendurch mal Luftholen kann..
Um es nicht ganz so primitiv umzusetzen, habe ich eine einfache, wiederverwendbare Variante gebaut:

Ein globales Array, das Funktionen aufnimmt. Und ein AT, das alle 10 Sekunden evtl. vorhandene Funktionen fifo abarbeitet. Da es zufriedenstellend funktioniert, möchte ich euch dran teilhaben lassen. Also wer es nachbauen möchte definiert sich ein AT im gewünschten Intervall

defmod at.execSubDelayed at +*00:00:10 {
execSubDelayed();
}

und erweitert die 99_myUtils.pm (ACHTUNG: @ATLIST muss ganz oben deklariert werden)

use POSIX;

sub
myUtils_Initialize($$)
{
  my ($hash) = @_;
  our @ATLIST;
}

# Enter you functions below _this_ line.
use IO::Socket;

sub subDelayed($;$) {
my ($functionName, $parameter)  = @_;
$parameter //= "";
$functionName .= ",";
push @main::ATLIST, $functionName.$parameter;
fhem("setreading at.execSubDelayed queue " . join(" | ", @main::ATLIST));
if((@main::ATLIST != 0) && (Value("at.execSubDelayed") eq "inactive")) {
fhem("set at.execSubDelayed active");
}
}

sub execSubDelayed() {
my $myFunc = shift @main::ATLIST;
my ($functionName, $parameter) = (split(/,\s*/, $myFunc, 2));
$parameter //= "";
my @params = ();
if ($parameter) {
@params = (split(/,\s*/, $parameter));
}
Log 4, "execSubDelayed functionName:$functionName parameter:$parameter params @params";
my $action = \&$functionName;
$action->(@params);
if(@main::ATLIST == 0) {
fhem("set at.execSubDelayed inactive");
fhem("setreading at.execSubDelayed queue 0");
} else {
fhem("setreading at.execSubDelayed queue " . join(" | ", @main::ATLIST));
}
}


Aufruf via

subDelayed("meineFunktion", "ParameterA,ParameterB, ParameterC")

Beispiel:

subDelayed("addLog","Wandthermostat.3.Weather,state");
subDelayed("addLog","TFK.*Sw.(01|02|04).*(Verschluss|Kipp),contact");


Vermutlich geht es auch schöner. Aber nicht mit sleep, zumindest bin ich mit sleep nicht glücklich geworden.
Wer ebenfalls seine Umgebung irgendwie optimieren konnte, bitte her mit den Infos!

Viel Spaß
Ronny
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB

rudolfkoenig

Thorsten hat fuer diesen Zweck vor kurzem PrioQueue gebaut, die Diskussion war hier: https://forum.fhem.de/index.php?topic=77890

#####################################
# Add a function to be executed after select returns. Only one function is
# executed after select returns.
# fn:   a function reference
# arg:  function argument
# nice: a number like in unix "nice". Smaller numbers mean higher priority.
#       limited to [-20,19], default 0
# returns the number of elements in the corrsponding queue
sub
PrioQueue_add($$;$)

FHEMAN

Ach prima. "Zwei Doofe ein Gedanke", wie man so schön sagt. Die Kategorie FHEM Development ist eine Fundgrube, die bisher komplett an mir vorbeiging. Obwohl mir (eher Endanwender) das teils auch schon zu sehr in die Tiefe geht. Ich verstehe zum Beispiel nicht richtig, in welcher Form ich dort Funktionsparameter übergebe.
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB