• Bitte schaltet eure Ad Blocker aus. SLinfo kann nur betrieben werden, wenn es durch Werbung Einnahmen erzielt. Vielen Dank!!
  • Wir freuen uns, wenn du dich in unserem Forum anmeldest. Bitte beachte, dass die Freigabe per Hand durchgeführt wird (Schutz vor Spammer). Damit kann die Freigabe bis zu 24 Stunden dauern.
  • Wir verwenden Cookies, um Inhalte und Anzeigen zu personalisieren, Funktionen für soziale Medien anbieten zu können und die Zugriffe auf unsere Website zu analysieren. Sie geben Einwilligung zu unseren Cookies, wenn Sie unsere Webseite weiterhin nutzen.

Gibt es "zu grosse" Werte für llSetTimerEvent?

argus Portal

Freund/in des Forums
Hallo

Wie der Titel schon sagt, würde ich gerne wissen, ob mit Problemen zu rechnen ist, wenn man sehr grosse Zeiten für llSetTimerEvent
angibt. Z.b., wenn ich einmal täglich einen Vorgang auslösen will : Das wären dann z.b.: 3600 * 24 = 86400 Sekunden.

Das interessiert mich generell. Aber da wir schon dabei sind: Gibt es eine sichere Möglichkeit, ein Script feststellen zu lassen, das
24 Stunden vorbei sind, ohne den Timer zu benutzen ?
 
Wenn Dein Script nach 24 h "aufwachen" und zwischenzeitlich möglichst wenig Last verursachen soll, ist ein Timer das Mittel der Wahl. Die Zeitspanne ist unkritisch, es wird ein Float übergeben. Floats gehen bis ca. 10^38 mit 32 Bit Auflösung.

Wenn Dein Script eh aktiv bleibt und an einer bestimmten Stelle des Codes regelmäßig vorbei kommt, ginge alternativ z.B. die Abfrage mit llGetUnixTime, das zählt in Sekunden hoch seit irgendwann 1970. Also Startwert merken und Schleife abbrechen bei Zielwert > Startwert + 86400.
 
Zuletzt bearbeitet:
Ich wollte nur sichergehen, ob es Erfahrungswerte gibt, die von extremen Werten abraten.

Leider läuft das Script nicht in einer Schleife. Es befindet sich meistens im Wartezustand.
Ich bin also auf jeden Fall auf ein Event angewiesen. Ich fragte auch deshalb, da es ja eine
neuere Funktion (Event) geben könnte, das noch nicht in der wiki erwähnt ist.
 
Timer sind recht robust und verbrauchen, wenn sie nicht im Millisekundentakt getriggert werden, wenig Resourcen.
Auch einen Simneustart überstehen sie.
Einziges Manko, sie sind nicht superexakt was idR kein bisschen stört.
http://wiki.secondlife.com/wiki/Timer schrieb:
The time between timer events can be longer than that specified with llSetTimerEvent, this is caused by:
Time dilation - See llGetRegionTimeDilation for more information;
Default event delay - Only so many events can be triggered per second;
Event Execution - If the execution of an event takes too long;...
Ich hatte jahrelang einen Visitorcounter, der mir nach Mitternacht eine Mail mit den Besuchern des Tages schickte.
Da gab es nie Ausfälle.

Eine denkbare Alternative wäre die Sleep Funktion, lass es knapp 24 Stunden schlafen und polle dann einige Minuten llGetUnixTime,
was dann beim Erreichen der Targetzeit den nächsten Sleep auslöst.

Für Perioden ab 24 Stunden stünden auch noch llGetWallclock/llGetGMTclock zur Verfügung (statt llGetUnixTime).
Die geben die verstrichenen Sekunden seit Mitternacht der entsprechenden Zeitzone aus, was aber die Rechnerei eher verlangsamt

integer llGetUnixTime() // schnellste Variante, Ganzzahlen und ein statischer Start (1.1.1970 00:00:00)
float llGetWallclock() // Sekunden seit Mitternacht, aber als Gleitkommazahl und die sind langsamer (dazu kommen noch Zeitzonenberechnungen)
 
Danke euch für die Antworten.

Dann bleibe ich beim Timer in dem Fall. Es handelt sich um ein Vermietersystem.

Thema llSleep: Das ist zumindest in OpenSim verpönt. Es soll eine regelrechte Serverqual sein.
 
Zumindest in SL ist llSleep letztendlich einfach ein beliebig setzbares Script Delay. Also ähnlich wie bei llEmail (das hat 20s delay) oder llSetPos (0.2s delay), nur eben irgendein 32-bit float Wert, der größer als 0.022s ist. (Bei kleineren Werten als die 22ms wird trotzdem immer ein ganzer Frame des Servers ausgesetzt). Während dieser Zeit macht das Script normal nichts - und belegt in den Frames, in denen das delay aktiv ist eigentlich auch keine CPU-Zeit.
D.h. llSleep ist zumindest in SL laut Kelly Linden eben kein Ressourcenfresser (Aussage von 2011). Kann aber gut sein, dass das früher mal anders war - da hat sich vor ein paar Jahren bisschen was geändert, aber heute werden Scripts auch nur noch abgearbeitet, wenn der Server freie Zeit hat. Kann aber sehr gut sein, dass das in OpenSim noch auf der alten Methode aufbaut. Und eben anders umgesetzt wird als in SL (das Serverseitig leider closed source ist).
 
Shirley hat recht.
Meine Tests haben ergeben: bis zu einer Schwelle von 0.027777777 Sekunden wird immer ein komplettes Frame übersprungen (vorausgesetzt die Frames sind konstant bei 45 Serverframes/Sekunde). Ab dieser Schwelle von 0.027777777 Sekunden wird mindestens ein Frame übersprungen. Ich vermute dass der Server hier in etwa in ganzen (ganzzahligen) Frames rechnet.
 
Klar wird der Timer mit llSleep eine große Belastung, wenn ihr mit so winzigen Intervallen rechnet. Solche Aussagen führen dann zu den Gerüchten, llSleep sei böse... :rolleyes: Argus fragte allerdings nach riesigen Zeitintervallen, deutlich länger als eine Minute (die mit Sicherheit unkritisch ist). Und wenn es um große Zeiten geht, ist llSleep immer deutlich ressourcensparender als eine Schleife, die dauernd das Script beschäftigt und irgendwelche Zeiten überprüft.

Mit so einer an der Frage vorbei geschriebenen Fachsimpelei stiftet ihr eher Verwirrung als zu helfen, sorry. :sad:
 
Es ist doch schon alles gesagt, @Mareta.
Es gibt entweder die Möglichkeit in einem wiederkehrenden Event den Timestamp mit einem global gespeicherten Wert zu vergleichen, oder den Timer, oder llSleep.
Keines davon sollte Probleme verursachen, und alles kommt auch mit längeren Intervallen gut klar.
Wobei 24 Stunden auch nicht wirklich lang sind an der Stelle.

Ich würde definitiv den Timer empfehlen. Bei llSleep reagiert das Skript 24 Stunden lang überhaupt nicht, das führt oft zu Verwirrungen. Und es kann sich in der Zeit auch ein zu großer Eventqueue aufbauen, so dass dann weitere Events nicht getriggert werden.
 
Ich finde es leider nicht wieder. Aber im IRC (#opensim-dev) wurde vor einiger Zeit einmal ausdrücklich von llSleep
abgeraten. Man solle, wo es möglich ist, immer stattdessen den Timer einsetzen.

Der Grund zu meiner Frage war, das ein sehr grosses Intervall im Grunde ein Auftrag an den Server ist. Rein instinktiv sah
ich einen Unterschied zu einem Script, das sich sozusagen ständig in "Erinnerung" bringt, weil es den Server so gut wie
pausenlos beschäftigt. Und nun lese ich hier, das der Timer sogar einen Regionneustart überlebt. :)
 
llSleep sorkt fuer eine kuenstliche verzoegerung, welche bei LAG sogar schlimmer wird.
llSetTimerEvent laeuft recht stabil und macht nach einem Region-Neustart weiter wo er aufhoerte, was bei einer festen zeitangabe jedoch fatale auswirkungen haben kann.

Darum bin ich bei manchen Sachen dazu ueber gegangen, einfach das Datum zu vergleichen.
Fuer einen Greeter oder MM Board ist sowas voellig ausreichend. wenn der Timer in dem Fall wie ich oben schon erwaehnte im 5 Minuten-Takt tickt, ist die maximale Verspaetung nach 24 Stunden lediglich 5 minuten, und gleicht sich taeglich aus. Selbst wenn die Region 30 - 45 Minuten fuer Rolling Restarts offline ist, sind es am naechsten Tag wieder nur 5 Minuten maximal die das Script hinter her haengt.

Wenn du es aber ganz genau haben moechtest, bist du Wahrscheinlich mit UnixTime am besten bedient, musst aber mehr rechnen.^^

LG
Dae
 
Das eine ist bei mir hier das grundsätzlich techn. Interesse. Das andere der praktische Einsatz. Bei meinem Vermietersystem setze ich den
Timer einfach nur als eine Art "regelmässige Wiederbelebung" ein. Dann verrechne ich per llGetUnixTime den zu Beginn des Mietvorgangs
gespeicherten Wert. Von daher sollte sich also eine nahezu beliebige Genauigkeit erreichen lassen.
 
@Argus: Im OpenSim gibt es noch ganz andere Probleme. Wenn Regionenbetreiber eine neue Version einspielen, dann löschen sie üblicherwese ihr OpenSim/bin Verzeichnis und kopieren die neue Version dort hin. Im Ergebnis sind alle Scripte resettet und werden neu gestartet. Das überlebt kein Timer, kein llSleep, da hilft nur zyklisches Schreiben in permanenten Speicher.

Zu Deinem konkreten Problem: Ich würde das Script mit llSleep z.B. stundenweise aufwecken und dann mit llGetUnixTime() kurz ausrechnen, ob irgendeine Aktivität nötig ist. Dann das Script wieder eine Stunde schlafen legen. Den Referenzwert würde ich in einer Eigenschaft des Prims - also außerhalb des Scripts - speichern, damit er auch Updates überlebt (Beispiel: llSetPrimitiveParams -> PRIM_DESC). Zugegebenermaßen ist das billig, aber dafür effektiv. ;)
 
Zuletzt bearbeitet:
Genauso mache ich das. Die Mietzeit bringe ich im Prim unter. Ich finde das nicht "billig".
Das ist die sicherste Methode, Daten dauerhaft unterzubringen. (Solange man nicht per
Script in Notecards schreiben kann und solange man keinen Server hat, auf dem man
Daten deponieren kann.)

Zu OpenSim: Natürlich gibt es da einige Probleme. Da steht aber auch kein millonenschweres
Unternehmen dahinter. Und nicht nur daran daran gemessen läuft OS bemerkenswert gut.

Die Sache mit llSleep hat aber nichts mit einem neu aufgesetzten System zu tun.
(Das da alles verloren geht ist klar. Ansonsten wäre es Voodoo ;-) )

Es ist in OS evtl. etwas buggy umgesetzt. Manche Leute scheinen dort
llSleep zu meiden, wie der Teufel das Weihwasser ;-)
 
Wie ich schon sagte, bei llSleep hast du das Problem (auch in Second Life), dass sich ein Eventqueue aufbauen kann. Je nachdem wie groß ein Eventqueue in Opensim werden kann, kann das durchaus auch Performance-Einbußen bringen, aber zumindest unerwünschte Nebenwirkungen deines Skripts.

Für soetwas sollte man besser einen Timer verwenden (llSetTimerEvent).
 
Für SL:
Scripts haben nach dem Kompilieren auf dem Server immer wieder "Stopmarken" zwischen wesentlichen Teilen und Events, an diesen Stellen kann das Script angehalten werden. Das ist etwa nach einem Abarbeiten von Events, aber auch nach bestimmten Funktionen. Und z.B. wenn für einen TP nötig kann das Script im Speicher an dieser Stelle eben auch komprimiert, an einen anderen Server geschickt, dort ausgepackt, in den Speicher des neuen Servers geschrieben und dort ab der selben Stelle weiter ausgeführt werden, an der es angehalten wurde. Scripts laufen also nicht kontinuierlich durch, sondern immer nur von Stopmarke bis Stopmarke.
Am Ende jedes Frames, der optimalerweise höchstens 22ms lang ist (da der Server mit 45 FPS läuft), schaut die Script Engine jetzt einfach nach welche Scripts im Simulator vorhanden sind und welche Scripts mit dem Weiterlaufen der Stopmarken dran sind. Ist im Frame freie Zeit für die Scripts vorhanden, dann werden sie weiter ausgeführt, die Stopmarken werden nach und nach abgearbeitet. Dabei nimmt der Server auch in Kauf, dass die FPS nicht stabil bleiben und leicht sinken, auf z.B. 30 FPS (den genauen Wert kenn ich nicht, das dürfte aber um den Dreh sein), das entspricht dann einer Frametime von 33ms. Reicht diese Zeit allerdings nicht mehr aus um alle Scripts mit einer Stopmarke abzuarbeiten, dann kommen die Stopmarken, die weiterlaufen hätten sollen, dies aber nicht mehr geschafft haben, an den Anfang des Stoppmarken-Stapels des nächsten Frames, die Betroffenen Scripten laufen nicht weiter und verbrauchen auch keine CPU-Zeit und stören den Server in diesem Frame nicht weiter. Erst wenn Zeit über ist und das script dann an der Reihe ist wird es wieder fortgesetzt. Und belastet den Server wieder mit Rechenzeit. Hat ein Script nun laufende Delay-Time, dann meldet es eben für eine gewisse Zeit einfach keine Stopmarken mit "ich will weiter laufen" - es wird im jeweils aktuellen Frame einfach nicht abgearbeitet. Belegt also eben auch keine CPU-Zeit außer für die Meta-Verwaltung des Delays in der Script-VM. Es ist eben dadurch keine Server-Last.
Deswegen kann man zumindest in SL bedenkenlos llSleep auch für lange Zeiträume nutzen wenn Will, dass ein Script überhaupt nichts macht in der Zeit. Ein Script mit z.B. schon 600s = 10 min Script Time verbraucht bereits nach kurzer Zeit "0.000050 ms of CPU time" oder so während es "läuft". Also eigentlich nichts. CPU-Last wird erst dann wieder generiert, wenn die Schlafzeit vorbei ist.

Zu viele Events können sich auch nicht wirklich aufstauen, pro Script können nur 64 Events in einen Queue. Werden mehr Events getriggert, dann werden die so lange ignoriert bis wieder Platz ist.
EDIT: Und jeder Event wird während des Sleep-Zustandes nur ein mal getriggert. D.h. wenn während des Sleep vier mal das Prim berührt wird, dann wird trortzdem nur ein einziges mal der touch-Event ausgelöst und nicht vier mal.

Das Einzige Problem mit llSleep, aber auch mit llSetTimerEvent ist, dass SL nicht "rund läuft", d.h. es kann eine time dilation geben. Dabei entsprechen 45 FPS eben einer time dilation von 1.0 und 22 FPS dann einer time dilation von 0.5. Was für Scripte leider bedeutet, dass die Scriptzeit in weiten Teilen nur halb so schnell vergeht wie normal. Das kann in ganz extremer Form dann auftreten, wenn eine Region leer ist und der Server auf "region idling" umschaltet, d.h. die Region wird zum Energiesparen auf "ganz langsam" runter gefahren und allenfalls ganz kurz für wichtige LSL-Funktionen (Netzwerkkommunikation) wieder auf 45FPS gesetzt.

==> Deswegen ist es in SL leider unerlässlich mit einem extrernen Zeitgeber (llGetUnixTime, llGetTimeStamp etc.) zu arbeiten, wenn man einen sehr langen Timer Event oder wenn irgendwie möglich einen sehr langen Sleep Event verwendet (der braucht weniger Ressourcen als ein Timer) und korrekte Zeitintervalle braucht. D.h. man muss z.B. das Script kurz vor dem geplanten Zeitintervall wieder aufwachen lassen um sich dann den richtigen Zeitpunkt mit einem schnelleren Timer für die entsprechende Aktion zu holen (z.B. jede Sekunde oder alle 5s mal abgleichen).

Für OpenSimulator:
Die Script-Engine ist dort komplett andes aufgebaut. Leider ist diese Software eher bisschen bescheidener und einfacher programmiert, deswegen ist llSleep da ein kleines Problem.
Das Problem ist, dass jedes Script dort mit einem Even einen eigenen Thread in der CPU belegt. Das ist normal kein Problem, denn Events sind für gewöhnlich Dinge in einem Script, die ziemlich schnell abgearbeitet sind. Worauf der Thread wieder freigegeben wird. Und normalerweise sitzt das Script einfach im Speicher rum und macht nichts ausser auf neue Events zu warten um damit einen Event zu belegen.
Läuft in einem Event allerdings ein llSleep - oder aber auch eine andere Funktion mit einem großen Delay wie llEmail ! - dann wird der Event eben nicht abgearbeitet und der Thread wird nicht freigegeben. Bei llEmail bedeutet das z.B., dass bei jedem Aufruf der Thread für 20s belegt wird. Aber auch andere Funktionen wie llSetLinkPrimitiveParams haben so ein Delay, hier sind es 0.2s. Was aber mit einer hinreichenden Anzahl an Scripts, die diese Funktion hinreichend schnell aufrufen direkt dazu führen kann, dass der Server so stark belastet wird, dass die Script-Engine einfach dicht ist.

Genau deswegen sollte man in OpenSimulator wenn irgendwie möglich mit Funktionen, die ein eingebautes Delay haben, äußerst sparsam umgehen und diese wirklich nur dann verwenden, wenn es gar nicht anders geht. Und llSLeep wenn irgendwie möglich nur für kurze Zeiten nutzen damit die Events wieder schnell abgearbeitet werden können.

Siehe auch http://www.kitely.com/forums/viewtopic.php?f=26&t=1149
 
Zuletzt bearbeitet:
Wie dem auch sei: bedenke dass bei der Verwendung von llSleep das Skript nicht reagiert, und es gegebenenfalls kompliziert werden kann, wenn man später dem Skript noch Funktionen hinzufügen möchte.
Ob llSetTimerEvent oder llSleep mehr oder weniger Ressourcen verbraucht kann ich nicht wirklich beurteilen, beides ist jedoch in Second Life zumindest absolut vernachlässigbar.
Und wie ich schon sagte, ich weiß nicht ob der Eventqueue in Opensim ebenfalls limitiert ist.
Ich rate in jedem Fall von der Verwendung von llSleep ab, weil es programmiertechnisch sehr unflexibel in der Handhabung ist.
 

Users who are viewing this thread

Zurück
Oben Unten