source: trunk/LATMOS-Accounts/lib/LATMOS/Accounts/SyncManager.pm @ 2358

Last change on this file since 2358 was 2220, checked in by nanardon, 5 years ago

Add module to recompute object value in background

File size: 6.5 KB
RevLine 
[861]1package LATMOS::Accounts::SyncManager;
2
3use strict;
4use warnings;
5use LATMOS::Accounts::Log;
6use LATMOS::Accounts;
[1200]7use Config::IniFiles;
[861]8
[1023]9=head1 NAME
10
11LATMOS::Accounts::SyncManager - Routine task manager
12
13=head1 DESCRIPTION
14
15Handle Task process run by L<la-sync-manager>
16
17=head1 FUNCTIONS
18
19=cut
20
21=head2 new($config)
22
23Instaciate object.
24
25C<$config> is a path to an alternative configuration file to default one.
26
27=cut
28
[861]29sub new {
30    my ($class, $config) = @_;
31
32    my $ini = Config::IniFiles->new(
33        -file => join('/', ($config || '/etc/latmos-accounts'),
34            'la-sync-manager.ini'),
35    ) or do {
36        la_log LA_ERR, "Cannot load config";
37        return;
38    };
39
[2220]40    foreach my $section (qw(update basessynchro refreshexpired updatedyndata)) {
[1198]41        if ( !grep {
42            lc($ini->val($_, 'type', '')) eq $section
43            } $ini->Sections ) {
44            $ini->newval("_$section", 'type', $section);
45        }
[1135]46    }
47
[861]48    bless {
49        ini => $ini,
50        config => $config,
51        lastrev => 0,
52    }, $class;
53}
54
[1023]55=head2 ini
56
57Return a reference to the L<Ini::Files> object handling configuration.
58
59=cut
60
[861]61sub ini { $_[0]->{ini} }
62
[1023]63=head2 dbrev
64
65Return the current base revision
66
67=cut
68
[1200]69sub dbrev {
70    my ($self) = @_;
71    my $LA = LATMOS::Accounts->new($self->{config}, noacl => 1);
72    my $base = $LA->base;
73    return $base->current_rev;
74}
[861]75
[1200]76sub _load_state_ini {
77    my ($self) = @_;
78    my $la = LATMOS::Accounts->new($self->{config}, noacl => 1);
[1023]79
[1200]80    my $state_file =  $la->val('_default_', 'state_dir', '/');
81    $state_file .= '/la-sync-manager.ini';
82    la_log(LA_DEBUG, "Status file is %s", $state_file);
83    if ($state_file && ! -w $state_file) {
84        # don't exists, we have to create it
85        open(my $handle, '>', $state_file) or do {
86            la_log(LA_ERR, "Cannot open build net status file %s",
87                $state_file);
88            return;
89        };
90        print $handle "[_default_]\n";
91        close($handle);
92    }
93    return Config::IniFiles->new(
94        -file => $state_file
95    );
96}
[1023]97
[1200]98=head2 get_last_rev($module)
99
100Return the last revision the module succeed
101
[1023]102=cut
103
[1200]104sub get_last_rev {
105    my ($self, $module) = @_;
106
[1736]107    my $ini = $self->_load_state_ini or return(0, 0);
[1200]108
109    return ($ini->val($module, 'rev', 0), $ini->val($module, 'time', 0));
[861]110}
111
[1023]112=head2 list_modules
113
114List configured task module
115
116=cut
117
[861]118sub list_modules {
119    my ($self) = @_;
120    $self->ini->Sections;
121}
122
[1824]123
124=head2 listSortedModules
125
126List configured module ordered for running
127
128=cut
129
130sub listSortedModules {
131    my ($self) = @_;
132
133    my %modules = ();
134
135    foreach my $module ($self->list_modules) {
[2017]136
137        $self->ini->val($module, 'disable') and do {
138            la_log(LA_DEBUG, "Module $module is disable, not running it");
139            next;
140        };
141
142        $modules{$module} = 1; # default
[1824]143        my $modtype = $self->ini->val($module, 'type', $module);
144        my $task = LATMOS::Accounts::Task->new(
145            $modtype,
146            config => $self->{config},
147            name   => $module,
148            syncm  => $self,
149        )
150            or do {
151            la_log(LA_ERR, 'Cannot load module %s', $modtype);
152            next;
153        };
154
155        $modules{$module} = $task->order;
156    }
157
158    return sort { $modules{$a} <=> $modules{$b} } keys %modules;
159}
160
[1200]161=head2 process_module($module)
[1023]162
163Process C<$module>.
164
165=cut
166
[861]167sub process_module {
[1200]168    my ($self, $module) = @_;
[861]169
[1016]170    eval {
171        if (!$self->ini->SectionExists($module)) {
172            la_log LA_ERR, "Cannot run inexistant module %s", $module;
173            return;
174        }
[861]175
[1016]176        my $modtype = $self->ini->val($module, 'type', $module);
177        my $task = LATMOS::Accounts::Task->new(
178            $modtype,
179            config => $self->{config},
[1200]180            name   => $module,
181            syncm  => $self,
[1016]182        )
183            or do {
184            la_log(LA_ERR, 'Cannot load module %s', $modtype);
185            return;
186        };
187        if (!$task->init) {
188            la_log(LA_ERR, 'init() failed for module %s', $module);
189            return;
190        }
[861]191
[1200]192        my $currentrev = $self->dbrev;
[1740]193        $task->needToBeRun($self, $module) or return 1;
[861]194
[1742]195        la_log LA_NOTICE, "Processing sync module %s (%s)", $module, $modtype;
196
[1016]197        my $res = $task->run;
198        if (!$res) {
[1203]199            my $ini = $self->_load_state_ini or return;
200            $ini->newval($module, 'error', LATMOS::Accounts::Log::lastmessage());
[1016]201            la_log LA_ERR, "Task %s did not end successfully", $module;
[1203]202            $ini->RewriteConfig;
203        } else {
204            $task->post if ($res);
205            my $ini = $self->_load_state_ini or return;
[1200]206
[1203]207            $ini->delval($module, 'error');
208            $ini->newval($module, 'rev', $currentrev);
209            my $time = time;
210            $ini->newval($module, 'time', $time);
211            $ini->SetParameterComment(
212                $module, 'time',
213                scalar(localtime(time)),
214            );
215            $ini->RewriteConfig;
[1200]216
[1203]217            la_log LA_DEBUG, "end process $module";
218        }
[1016]219        return $res;
220    };
221
222    if ($@) {
223        la_log(LA_CRIT, 'Fatal Perl Error: %s', $@);
224        return;
[1017]225    } else {
226        return 1;
[861]227    }
228}
229
[1206]230=head2 reset_module_savepoint($module)
[1201]231
[1206]232Reset the savepoint for module C<$module> to force it to run at next
[1201]233synchronisation.
234
235=cut
236
[1206]237sub reset_module_savepoint {
[1201]238    my ($self, $module) = @_;
239    if (!$self->ini->SectionExists($module)) {
240        la_log LA_ERR, "Cannot run inexistant module %s", $module;
241        return;
242    }
243
244    my $modtype = $self->ini->val($module, 'type', $module);
245    my $task = LATMOS::Accounts::Task->new(
246        $modtype,
247        config => $self->{config},
248        name   => $module,
249        syncm  => $self,
250    )
251        or do {
252        la_log(LA_ERR, 'Cannot load module %s', $modtype);
253        return;
254    };
255    $task->init or do {
256        la_log LA_ERR, "Cannot init module %s", $_;
257        return;
258    };
259
260    my $ini = $self->_load_state_ini or return;
261
262    $ini->delval($module, 'rev');
263    $ini->newval($module, 'time', 0);
264    $ini->SetParameterComment(
265        $module, 'time',
266        'Reset to 0 the ' . scalar(localtime(time)),
267    );
268
[1206]269    $task->reset_savepoint; # Specific reset
[1201]270    $ini->RewriteConfig;
271}
272
[861]2731;
[1023]274
275__END__
276
277=head1 SEE ALSO
278
279L<LATMOS::Accountsi::Task>
280
281=head1 AUTHOR
282
283Olivier Thauvin, E<lt>olivier.thauvin@latmos.ipsl.frE<gt>
284
285=head1 COPYRIGHT AND LICENSE
286
287Copyright (C) 2012 CNRS SA/CETP/LATMOS
288
289This library is free software; you can redistribute it and/or modify
290it under the same terms as Perl itself, either Perl version 5.10.0 or,
291at your option, any later version of Perl 5 you may have available.
292
293=cut
Note: See TracBrowser for help on using the repository browser.