--- deliantra/server/lib/cf.pm 2007/05/05 05:40:27 1.263 +++ deliantra/server/lib/cf.pm 2007/05/19 00:08:11 1.267 @@ -92,6 +92,10 @@ # used to convert map paths into valid unix filenames by replacing / by ∕ our $PATH_SEP = "∕"; # U+2215, chosen purely for visual reasons +our $LOAD; # a number between 0 (idle) and 1 (too many objects) +our $LOADAVG; # same thing, but with alpha-smoothing +our $tick_start; # for load detecting purposes + binmode STDOUT; binmode STDERR; @@ -141,6 +145,16 @@ The interval between server ticks, in seconds. +=item $cf::LOADAVG + +The current CPU load on the server (alpha-smoothed), as a value between 0 +(none) and 1 (overloaded), indicating how much time is spent on processing +objects per tick. Healthy values are < 0.5. + +=item $cf::LOAD + +The raw value load value from the last tick. + =item %cf::CFG Configuration for the server, loaded from C, or @@ -320,6 +334,8 @@ my ($job) = @_; if ($Coro::current == $Coro::main) { + my $time = Event::time; + # this is the main coro, too bad, we have to block # till the operation succeeds, freezing the server :/ @@ -340,6 +356,13 @@ Coro::cede or Event::one_event; } + $time = Event::time - $time; + + LOG llevError | logBacktrace, Carp::longmess "long sync job" + if $time > $TICK * 0.5 && $TICK_WATCHER->is_active; + + $tick_start += $time; # do not account sync jobs to server load + wantarray ? @res : $res[0] } else { # we are in another coroutine, how wonderful, everything just works @@ -369,11 +392,17 @@ } sub write_runtime { - my $guard = cf::lock_acquire "write_runtime"; - my $runtime = "$LOCALDIR/runtime"; - warn "starting to write runtime...\n";#d# + # first touch the runtime file to show we are still running: + # the fsync below can take a very very long time. + + if (my $fh = aio_open $runtime, O_WRONLY, 0) { + utime undef, undef, $fh; + } + + my $guard = cf::lock_acquire "write_runtime"; + my $fh = aio_open "$runtime~", O_WRONLY | O_CREAT, 0644 or return; @@ -388,13 +417,16 @@ aio_fsync $fh and return; + # touch it again to show we are up-to-date + utime undef, undef, $fh; + close $fh or return; aio_rename "$runtime~", $runtime and return; - warn "... done writing runtime.\n";#d# + warn "runtime file written.\n";#d# 1 } @@ -597,7 +629,7 @@ } elsif ($type eq "subtype") { defined $object_type or Carp::croak "subtype specified without type"; my $object_subtype = shift @arg; - $registry = $CB_TYPE[$object_type + $object_subtype * NUM_SUBTYPES] ||= []; + $registry = $CB_TYPE[$object_type + $object_subtype * NUM_TYPES] ||= []; } elsif ($type eq "package") { my $pkg = shift @arg; @@ -648,6 +680,7 @@ } else { _attach shift->_attach_registry, @_; } + _recalc_want; }; # all those should be optimised @@ -660,6 +693,7 @@ } else { Carp::croak "cannot, currently, detach class attachments"; } + _recalc_want; }; sub cf::attachable::attached { @@ -2829,7 +2863,7 @@ return; } - $NOW = Event::time; + $NOW = $tick_start = Event::time; cf::server_tick; # one server iteration @@ -2847,12 +2881,6 @@ # my $AFTER = Event::time; # warn $AFTER - $NOW;#d# - # if we are delayed by four ticks or more, skip them all - $NEXT_TICK = Event::time if Event::time >= $NEXT_TICK + $TICK * 4; - - $TICK_WATCHER->at ($NEXT_TICK); - $TICK_WATCHER->start; - if (my $sig = shift @WAIT_FOR_TICK_BEGIN) { $sig->send; } @@ -2860,7 +2888,20 @@ $sig->send; } + $NOW = Event::time; + + # if we are delayed by four ticks or more, skip them all + $NEXT_TICK = $NOW if $NOW >= $NEXT_TICK + $TICK * 4; + + $TICK_WATCHER->at ($NEXT_TICK); + $TICK_WATCHER->start; + + $LOAD = ($NOW - $tick_start) / $TICK; + $LOADAVG = $LOADAVG * 0.75 + $LOAD * 0.25; + _post_tick; + + }, );