1 | #!/bin/env perl |
---|
2 | |
---|
3 | use strict; |
---|
4 | use warnings; |
---|
5 | use Sophie::Base; |
---|
6 | use Sophie::Base::RpmsPath; |
---|
7 | use Linux::Inotify2; |
---|
8 | use POSIX ":sys_wait_h"; |
---|
9 | use Getopt::Long; |
---|
10 | |
---|
11 | GetOptions( |
---|
12 | 'bdelay=i' => \my $updated_inotify, |
---|
13 | 'd|daemon' => \my $daemon, |
---|
14 | ) or die "Wrong options"; |
---|
15 | |
---|
16 | $SIG{CHLD} = sub { wait }; |
---|
17 | |
---|
18 | my %modified_paths; |
---|
19 | my $inotify = undef; |
---|
20 | $updated_inotify ||= 300; |
---|
21 | |
---|
22 | if ($daemon) { |
---|
23 | if (fork()) { |
---|
24 | exit(0); |
---|
25 | } |
---|
26 | } |
---|
27 | |
---|
28 | alarm($updated_inotify); |
---|
29 | while (1) { |
---|
30 | local $SIG{ALRM} = sub { |
---|
31 | $inotify = undef; |
---|
32 | warn "reparse paths"; |
---|
33 | alarm($updated_inotify); |
---|
34 | }; |
---|
35 | if (update_base(keys %modified_paths)) { |
---|
36 | %modified_paths = (); |
---|
37 | } |
---|
38 | $inotify ||= inotify_path(); |
---|
39 | $inotify->poll; |
---|
40 | } |
---|
41 | |
---|
42 | sub inotify_path { |
---|
43 | |
---|
44 | my $i = Linux::Inotify2->new; |
---|
45 | my $sophie = Sophie::Base->connect; |
---|
46 | |
---|
47 | foreach ($sophie->resultset('Paths')->get_column('path')->all) { |
---|
48 | $i->watch( |
---|
49 | $_, |
---|
50 | IN_DELETE | IN_MODIFY | IN_CREATE, |
---|
51 | sub { |
---|
52 | my $e = shift; |
---|
53 | warn $e->w->name; |
---|
54 | $modified_paths{$e->w->name} = 1; |
---|
55 | 1; |
---|
56 | } |
---|
57 | ) |
---|
58 | } |
---|
59 | |
---|
60 | $i; |
---|
61 | } |
---|
62 | |
---|
63 | sub update_base { |
---|
64 | my @path = @_; |
---|
65 | |
---|
66 | if (waitpid(-1, &WNOHANG) != -1) { |
---|
67 | warn "child still running"; |
---|
68 | return; |
---|
69 | } |
---|
70 | warn "updating base"; |
---|
71 | |
---|
72 | my @pkey; |
---|
73 | { |
---|
74 | my $sophie = Sophie::Base->connect or do { |
---|
75 | die "cannot read config file\n"; |
---|
76 | }; |
---|
77 | @pkey = $sophie->resultset('Paths')->search( |
---|
78 | path => [ @path ], |
---|
79 | )->get_column('d_path_key')->all; |
---|
80 | push(@pkey, $sophie->resultset('Paths')->search({ |
---|
81 | updated => [ undef, |
---|
82 | \[ " < now() - '6 hours'::interval"], |
---|
83 | ], |
---|
84 | })->get_column('d_path_key')->all); |
---|
85 | my %uniq = map { $_ => 1 } @pkey; |
---|
86 | @pkey = keys %uniq; |
---|
87 | } |
---|
88 | |
---|
89 | return 1 if (!@pkey); |
---|
90 | |
---|
91 | if (my $pid = fork()) { |
---|
92 | } else { |
---|
93 | |
---|
94 | |
---|
95 | my $NB_PAR = 2; |
---|
96 | my @split; |
---|
97 | my $div = @pkey / $NB_PAR; |
---|
98 | |
---|
99 | for (my $i = 0; $i < $NB_PAR - 1; $i++) { |
---|
100 | $split[$i] = [ splice(@pkey, 0, $div) ]; |
---|
101 | } |
---|
102 | $split[$NB_PAR -1] = [ @pkey ]; |
---|
103 | foreach my $job (@split) { |
---|
104 | @{$job || []} or next; |
---|
105 | |
---|
106 | if (fork()) { |
---|
107 | } else { |
---|
108 | |
---|
109 | foreach my $pathkey (@{ $job }) { |
---|
110 | my @delta = Sophie::Base::RpmsPath->new($pathkey) |
---|
111 | ->find_delta; |
---|
112 | while (my @d = splice(@delta, 0, 25)) { |
---|
113 | my $path = Sophie::Base::RpmsPath->new($pathkey); |
---|
114 | $path->update_content(@d); |
---|
115 | $path->db->disconnect; |
---|
116 | } |
---|
117 | Sophie::Base::RpmsPath->new($pathkey)->set_updated; |
---|
118 | } |
---|
119 | exit(0); |
---|
120 | } |
---|
121 | } |
---|
122 | 1 while(waitpid(-1, 0) <= 0); |
---|
123 | exit(0); |
---|
124 | } |
---|
125 | return 1; |
---|
126 | } |
---|
127 | |
---|