1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
package MasterServer::Core::Schedulers;
use strict;
use warnings;
use AnyEvent;
use POSIX qw/strftime/;
use Exporter 'import';
use DBI;
our @EXPORT = qw |
long_periodic_tasks
short_periodic_tasks
|;
################################################################################
## tasks that are executed only once or twice per hour
################################################################################
sub long_periodic_tasks {
my $self = shift;
my $prev = 0;
return AnyEvent->timer (
after => 30, # 30 seconds grace time
interval => 3600, # execute every hour
cb => sub {
# update Killing Floor stats
$self->read_kfstats() if $self->{kfstats_enabled};
# delete old masterserver applets that have been unresponsive for a while now
$self->remove_unresponsive_applets() if (defined $self->{firstrun});
# time spacer
my $t = 0;
# clean out handles from the previous round (executed or not)
$self->{scope}->{sync} = ();
# Synchronize with all other 333networks masterservers that are uplinking,
# added by synchronization or manually listed.
if ($self->{sync_enabled}) {
# get serverlist
my $masterserverlist = $self->get_server(
updated => 3600,
gamename => "333networks",
);
foreach my $ms (@{$masterserverlist}) {
# add 5 second delay to spread network/server load
$self->{scope}->{sync}->{$t} = AnyEvent->timer(
after => 5*$t++,
cb => sub{$self->sync_with_master($ms)}
) if ($ms->{hostport} > 0);
}
}
# do NOT reset $t, keep padding time -- you should not have more than 300
# entries in applets/syncer in total anyway.
# Query Epic Games-based UCC applets periodically to get an additional
# list of online UT, Unreal and other game servers.
if ($self->{master_applet_enabled}) {
# get applet list
my $appletlist = $self->get_masterserver_applets();
for my $ms (@{$appletlist}) {
# add 5 second delay to spread network/server load
$self->{scope}->{sync}->{$t} = AnyEvent->timer(
after => 5*$t++,
cb => sub{$self->query_applet($ms)}
);
}
}
#
# very long-running tasks, like database dumps
# interval from config
#
my $curr = 0;
$curr = strftime('%d',localtime) if ($self->{dump_db} =~ /^daily$/i );
$curr = strftime('%U',localtime) if ($self->{dump_db} =~ /^weekly$/i );
$curr = strftime('%m',localtime) if ($self->{dump_db} =~ /^monthly$/i);
$curr = strftime('%Y',localtime) if ($self->{dump_db} =~ /^yearly$/i );
# on change, execute
if ($prev < $curr) {
# skip on first run
if ($prev == 0) {
# update timer and loop
$prev = $curr;
return;
}
# dump db
$self->dump_database();
# update timekeeper
$prev = $curr;
}
},
);
}
################################################################################
## tasks that are executed every few minutes
################################################################################
sub short_periodic_tasks {
my $self = shift;
return AnyEvent->timer (
after => 10,
interval => 120,
cb => sub {
# update stats on direct beacons and total number of servers
$self->update_stats();
# determine whether servers are still uplinking to us. If not, toggle.
$self->write_direct_beacons() if (defined $self->{firstrun});
# delete old servers from the "pending" list (except for the first run)
$self->delete_old_pending() if (defined $self->{firstrun});
# uplink to other 333networks masterservers with heartbeats, so other
# masterservers can find us too
$self->send_heartbeats();
},
);
}
1;
|