File Coverage

blib/lib/App/MonM/Notifier/Store.pm
Criterion Covered Total %
statement 191 250 76.4
branch 41 102 40.2
condition 20 78 25.6
subroutine 36 40 90.0
pod 15 15 100.0
total 303 485 62.4


line stmt bran cond sub pod time code
1             package App::MonM::Notifier::Store; # $Id: Store.pm 81 2022-09-16 10:21:57Z abalama $
2 2     2   48913 use strict;
  2         9  
  2         45  
3 2     2   421 use utf8;
  2         13  
  2         10  
4              
5             =encoding utf8
6              
7             =head1 NAME
8              
9             App::MonM::Notifier::Store - monotifier store class
10              
11             =head1 VERSION
12              
13             Version 1.02
14              
15             =head1 SYNOPSIS
16              
17             use App::MonM::Notifier::Store;
18              
19             my $store = App::MonM::Notifier::Store->new(
20             dsn => "DBI:mysql:database=monotifier;host=mysql.example.com",
21             user => "username",
22             password => "password",
23             set => [
24             "RaiseError 0",
25             "PrintError 0",
26             "mysql_enable_utf8 1",
27             ],
28             expires => 3600*24*7,
29             maxtime => 300,
30             );
31              
32             die($store->error) if $store->error;
33              
34             =head1 DESCRIPTION
35              
36             DBI interface for monotifier store. This module provides store methods
37              
38             =head2 new
39              
40             my $store = App::MonM::Notifier::Store->new(
41             dsn => "DBI:mysql:database=monotifier;host=mysql.example.com",
42             user => "username",
43             password => "password",
44             set => [
45             "RaiseError 0",
46             "PrintError 0",
47             "mysql_enable_utf8 1",
48             ],
49             expires => 3600*24*7,
50             maxtime => 300,
51             );
52              
53             Creates DBI object
54              
55             =over 8
56              
57             =item B
58              
59             Time in seconds of life of database record
60              
61             =item B
62              
63             Max time in seconds to sending one message
64              
65             =back
66              
67             =head2 cleanup
68              
69             my $st = $store->cleanup;
70              
71             Removes permanently queue entities based on how old they are
72              
73             =head2 dequeue
74              
75             my $st = $store->dequeue(
76             id => 1,
77             );
78              
79             Dequeues the element by setting success status (STATUS_SENT)
80              
81             =head2 delById
82              
83             $store->delById($id) or die($store->error);
84              
85             Delete record by id
86              
87             =head2 dsn
88              
89             my $dsn = $store->dsn;
90              
91             Returns DSN string of current database connection
92              
93             =head2 enqueue
94              
95             $store->enqueue(
96             to => $user,
97             channel => $ch_name,
98             subject => $subject,
99             message => $message,
100             attributes => $ch, # Channel attributes
101             ) or die($store->error);
102              
103             Adds a new element at the end of the current queue
104             and returns queue element ID
105              
106             =head2 error
107              
108             my $error = $store->error;
109              
110             Returns error message
111              
112             my $error = $store->error( "Error message" );
113              
114             Sets error message if argument is provided.
115              
116             =head2 getById
117              
118             my %data = $store->getById($id);
119              
120             Returns data from database by id
121              
122             =head2 getAll
123              
124             my @table = $store->getAll();
125             my @table_100 = $store->getAll(100);
126              
127             Returns data from database with limit supporting
128              
129             =head2 is_sqlite
130              
131             print $store->is_sqlite ? "Is SQLite" : "Is not SQLite"
132              
133             Returns true if type of current database is SQLite
134              
135             =head2 ping
136              
137             $store->ping ? 'OK' : 'Database session is expired';
138              
139             Checks the connection to database
140              
141             =head2 requeue
142              
143             my $st = $store->requeue(
144             id => 1,
145             code => 2,
146             error => "My Error",
147             );
148              
149             Requeue entities that have been retrieved for processing early; sets status to STATUS_FAIL
150              
151             =head2 retrieve
152              
153             my $entity = $store->retrieve(STATUS_FAIL);
154              
155             Retrieves the next entity from the queue and returns it as hashref
156             or undef if no entity
157              
158             =head2 serializer
159              
160             my $serializer = $store->serializer;
161              
162             Returns serializer object
163              
164             =head2 purge
165              
166             $store->purge or die($store->error);
167              
168             Delete all records
169              
170             =head1 DDL
171              
172             CREATE TABLE IF NOT EXISTS monotifier (
173             `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,
174             `to` CHAR(255), -- Recipient name
175             `channel` CHAR(255), -- Recipient channel
176             `subject` TEXT, -- Message subject
177             `message` TEXT, -- Message content (BASE64)
178             `attributes` TEXT, -- Message attributes (JSON)
179             `published` BIGINT(20), -- The publication time (unixtime)
180             `scheduled` BIGINT(20), -- The scheduled time (unixtime)
181             `expired` BIGINT(20), -- The expiration time (unixtime)
182             `sent` BIGINT(20), -- The send time
183             `attempt` INTEGER DEFAULT 0, -- Count of failed attempts
184             `status` CHAR(32), -- Status of transaction
185             `errcode` INT(11), -- Error code
186             `errmsg` TEXT -- Error message
187             )
188              
189             =head1 ERRORCODES
190              
191             0 -- No errors found
192             1 -- Error of the notifier level (notify method)
193             2 -- Error of the notifier level (remind method)
194             255 -- Error of the cleanup level
195              
196             =head1 SEE ALSO
197              
198             L, L
199              
200             =head1 AUTHOR
201              
202             Serż Minus (Sergey Lepenkov) L Eabalama@cpan.orgE
203              
204             =head1 COPYRIGHT
205              
206             Copyright (C) 1998-2022 D&D Corporation. All Rights Reserved
207              
208             =head1 LICENSE
209              
210             This program is free software; you can redistribute it and/or
211             modify it under the same terms as Perl itself.
212              
213             See C file and L
214              
215             =cut
216              
217 2     2   90 use vars qw/$VERSION/;
  2         3  
  2         94  
218             $VERSION = '1.02';
219              
220 2     2   11 use File::Spec;
  2         3  
  2         36  
221 2     2   325 use MIME::Base64 qw/encode_base64 decode_base64/;
  2         454  
  2         89  
222              
223 2     2   762 use CTK::DBI;
  2         154694  
  2         52  
224 2     2   13 use CTK::Util qw/ read_attributes touch /;
  2         4  
  2         80  
225 2     2   367 use CTK::ConfGenUtil;
  2         821  
  2         112  
226 2     2   339 use CTK::TFVals qw/ :ALL /;
  2         1453  
  2         294  
227 2     2   761 use CTK::Serializer;
  2         50842  
  2         57  
228              
229 2     2   331 use App::MonM::Const;
  2         1737  
  2         127  
230 2     2   354 use App::MonM::Util qw/ set2attr /;
  2         42350  
  2         178  
231              
232             use constant {
233 2         227 EXPIRES => 30*24*60*60, # 30 days max (how time to hold of messages)
234             MAXTIME => 300, # 5 min
235             JSON_ATTRS => [
236             { # For serialize
237             utf8 => 0,
238             pretty => 1,
239             allow_nonref => 1,
240             allow_blessed => 1,
241             },
242             { # For deserialize
243             utf8 => 0,
244             allow_nonref => 1,
245             allow_blessed => 1,
246             },
247             ],
248              
249             # Database
250             DB_FILENAME_NASK => 'monotifier-%s.db', # username
251             DEFAULT_DSN_MASK => 'dbi:SQLite:dbname=%s',
252             DEFAULT_DBI_ATTR => {
253             dsn => '', # See DEFAULT_DSN_MASK
254             user => '',
255             password => '',
256             set => [
257             'RaiseError 0',
258             'PrintError 0',
259             'sqlite_unicode 1',
260             ],
261             },
262              
263             # Statuses
264             STATUS_NEW => 'NEW',
265             STATUS_BUSY => 'BUSY',
266             STATUS_FAIL => 'FAIL', # See Attempt
267             STATUS_SENT => 'SENT',
268 2     2   14 };
  2         3  
269              
270 2     2   10 use constant MONOTIFIER_DDL => <<'DDL';
  2         3  
  2         81  
271             CREATE TABLE IF NOT EXISTS monotifier (
272             `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,
273             `to` CHAR(255), -- Recipient name
274             `channel` CHAR(255), -- Recipient channel
275             `subject` TEXT, -- Message subject
276             `message` TEXT, -- Message content (BASE64)
277             `attributes` TEXT, -- Message attributes (JSON)
278             `published` BIGINT(20), -- The publication time (unixtime)
279             `scheduled` BIGINT(20), -- The scheduled time (unixtime)
280             `expired` BIGINT(20), -- The expiration time (unixtime)
281             `sent` BIGINT(20), -- The send time
282             `attempt` INTEGER DEFAULT 0, -- Count of failed attempts
283             `status` CHAR(32), -- Status of transaction
284             `errcode` INT(11), -- Error code
285             `errmsg` TEXT -- Error message
286             )
287             DDL
288              
289 2     2   10 use constant MONOTIFIER_ADD => <<'DML';
  2         13  
  2         82  
290             INSERT INTO monotifier
291             (`to`,`channel`,`subject`,`message`,`attributes`,`published`,`scheduled`,`expired`,`sent`,`attempt`,`status`,`errcode`,`errmsg`)
292             VALUES
293             (?,?,?,?,?,?,?,?,?,?,?,?,?)
294             DML
295              
296 2     2   10 use constant MONOTIFIER_GET_NEXT => <<'DML';
  2         3  
  2         65  
297             SELECT `id`,`to`,`channel`,`subject`,`message`,`attributes`,`published`,`scheduled`,`expired`,`sent`,`attempt`,`status`,`errcode`,`errmsg`
298             FROM `monotifier`
299             WHERE `scheduled` <= ? AND `status` = ?
300             LIMIT 1
301             DML
302              
303 2     2   8 use constant MONOTIFIER_UPDATE_STATUS => <<'DML';
  2         3  
  2         86  
304             UPDATE `monotifier`
305             SET `status` = ?, `scheduled` = ?, `sent` = ?, `attempt` = ?, `errcode` = ?, `errmsg` = ?
306             WHERE `id` = ?
307             DML
308              
309 2     2   10 use constant MONOTIFIER_UPDATE_ERROR => <<'DML';
  2         2  
  2         79  
310             UPDATE `monotifier`
311             SET `status` = ?, `errcode` = ?, `errmsg` = ?
312             WHERE `id` = ?
313             DML
314              
315 2     2   9 use constant MONOTIFIER_CLEANUP => <<'DML';
  2         17  
  2         82  
316             DELETE FROM `monotifier`
317             WHERE `expired` <= ?
318             DML
319              
320 2     2   9 use constant MONOTIFIER_FLUSH => <<'DML';
  2         3  
  2         91  
321             UPDATE `monotifier`
322             SET `status` = ?, `errcode` = ?, `errmsg` = ?
323             WHERE (`status` = ? OR `status` = ?) AND `scheduled` < ?
324             DML
325              
326 2     2   11 use constant MONOTIFIER_PURGE => <<'DML';
  2         3  
  2         66  
327             DELETE FROM monotifier
328             DML
329              
330 2     2   7 use constant MONOTIFIER_GET_ALL => <<'DML';
  2         3  
  2         171  
331             SELECT `id`,`to`,`channel`,`subject`,`message`,`attributes`,`published`,`scheduled`,`expired`,`sent`,`attempt`,`status`,`errcode`,`errmsg`
332             FROM monotifier
333             ORDER BY `id` DESC
334             DML
335              
336 2     2   11 use constant MONOTIFIER_GET_BY_ID => <<'DML';
  2         3  
  2         79  
337             SELECT `id`,`to`,`channel`,`subject`,`message`,`attributes`,`published`,`scheduled`,`expired`,`sent`,`attempt`,`status`,`errcode`,`errmsg`
338             FROM monotifier
339             WHERE `id` = ?
340             DML
341              
342 2     2   9 use constant MONOTIFIER_DEL_BY_ID => <<'DML';
  2         2  
  2         3579  
343             DELETE FROM monotifier WHERE `id` = ?
344             DML
345              
346             sub new {
347 1     1 1 69 my $class = shift;
348 1         4 my %args = @_;
349 1 50       4 unless ($args{dsn}) {
350 1         1 my $dda = DEFAULT_DBI_ATTR;
351 1         5 foreach (%$dda) {
352 8   66     21 $args{$_} //= $dda->{$_}
353             }
354             }
355 1   0     160 my $username = getlogin() || (getpwuid($>))[0] || $ENV{LOGNAME} || $ENV{USER} || "anonymous";
356 1         6 my $filename = sprintf(DB_FILENAME_NASK, $username);
357 1   33     4 my $file = $args{file} || File::Spec->catfile(File::Spec->tmpdir(), $filename);
358 1   33     4 my $dsn = $args{dsn} || sprintf(DEFAULT_DSN_MASK, $file);
359              
360             # DB
361             my $db = CTK::DBI->new(
362             -dsn => $dsn,
363             -debug => 0,
364             -username => $args{'user'},
365             -password => $args{'password'},
366             -attr => set2attr($args{'set'}),
367             $args{timeout} ? (
368             -timeout_connect => $args{timeout},
369             -timeout_request => $args{timeout},
370 1 50       6 ) : (),
371             );
372 1 50       8936 my $dbh = $db->connect if $db;
373              
374             # SQLite
375 1         8 my $fnew = 0;
376 1         2 my $issqlite = 0;
377 1 50 33     7 if ($dbh && $dsn =~ /SQLite/i) {
378 1         5 $file = $dbh->sqlite_db_filename();
379 1 50 33     26 unless ($file && (-e $file) && !(-z $file)) {
      33        
380 1         19 touch($file);
381 1         95 chmod(0666, $file);
382 1         3 $fnew = 1;
383             }
384 1         2 $issqlite = 1;
385             }
386              
387             # Errors
388 1         2 my $error = "";
389 1 50       11 if (!$db) {
    50          
    50          
390 0         0 $error = sprintf("Can't init database \"%s\"", $dsn);
391             } elsif (!$dbh) {
392 0   0     0 $error = sprintf("Can't connect to database \"%s\": %s", $dsn, $DBI::errstr || "unknown error");
393             } elsif ($fnew) {
394 1         6 $db->execute(MONOTIFIER_DDL);
395 1 50       11413 $error = $dbh->errstr() if $dbh->err;
396             }
397 1 50       4 unless ($error) {
398 1 50 0     4 $error = sprintf("Can't init database \"%s\". Ping failed: %s",
399             $dsn, $dbh->errstr() || "unknown error") unless $dbh->ping;
400             }
401              
402             my $self = bless {
403             file => $file,
404             issqlite=> $issqlite,
405             dsn => $dsn,
406             error => $error,
407             dbi => $db,
408             expires => $args{expires} || EXPIRES,
409 1   50     44 maxtime => $args{maxtime} || MAXTIME,
      50        
410             serializer => CTK::Serializer->new('json', attrs => { json => JSON_ATTRS }),
411             }, $class;
412              
413 1         72 return $self;
414             }
415             sub error {
416 10     10 1 23 my $self = shift;
417 10         13 my $err = shift;
418 10 100       29 return $self->{error} unless defined $err;
419 7         11 $self->{error} = $err;
420 7         10 return $self->{error};
421             }
422             sub ping {
423 7     7 1 12 my $self = shift;
424 7 50       15 return 0 unless $self->{dsn};
425 7         9 my $dbi = $self->{dbi};
426 7 50       12 return 0 unless $dbi;
427 7         9 my $dbh = $dbi->{dbh};
428 7 50       13 return 0 unless $dbh;
429 7 50       32 return 1 unless $dbh->can('ping');
430 7         24 return $dbh->ping();
431             }
432             sub dsn {
433 0     0 1 0 my $self = shift;
434 0         0 return $self->{dsn};
435             }
436             sub serializer {
437 4     4 1 9 my $self = shift;
438 4         18 return $self->{serializer};
439             }
440             sub is_sqlite {
441 0     0 1 0 my $self = shift;
442 0 0       0 return $self->{issqlite} ? 1 : 0;
443             }
444              
445             # CRUD Methods
446              
447             sub getAll {
448 1     1 1 2 my $self = shift;
449 1   50     4 my $limit = shift || 0;
450 1 50       2 return () unless $self->ping;
451 1         27 $self->error("");
452 1         2 my $dbi = $self->{dbi};
453              
454 1 50       8 my @tbl = $dbi->table(sprintf("%s%s", MONOTIFIER_GET_ALL, $limit ? " LIMIT $limit" : "" ));
455 1 50       210 if ($dbi->connect->err) {
456 0         0 $self->error(sprintf("Can't get records: %s", uv2null($dbi->connect->errstr)));
457 0         0 return ();
458             }
459 1         10 return @tbl;
460             }
461             sub getById {
462 0     0 1 0 my $self = shift;
463 0   0     0 my $id = shift || 0;
464 0         0 my $dbi = $self->{dbi};
465 0         0 $self->error("");
466              
467 0         0 my %rec = $dbi->recordh(MONOTIFIER_GET_BY_ID, $id);
468 0 0       0 if ($dbi->connect->err) {
469 0         0 $self->error(sprintf("Can't get record: %s", uv2null($dbi->connect->errstr)));
470 0         0 return ();
471             }
472              
473 0 0 0     0 if (defined($rec{message}) && length($rec{message})) {
474 0         0 $rec{message} = decode_base64($rec{message});
475             }
476 0 0 0     0 if (defined($rec{attributes}) && length($rec{attributes})) {
477 0         0 $rec{attributes} = $self->serializer->deserialize($rec{attributes});
478 0 0       0 unless ($self->serializer->status) {
479 0         0 $self->error(sprintf("Can't deserialize channel attributes: %s", uv2null($self->serializer->error)));
480 0         0 return ();
481             }
482             }
483              
484 0         0 return %rec;
485             }
486             sub delById {
487 0     0 1 0 my $self = shift;
488 0   0     0 my $id = shift || 0;
489 0         0 my $dbi = $self->{dbi};
490 0         0 $self->error("");
491              
492 0         0 $dbi->execute(MONOTIFIER_DEL_BY_ID, $id);
493 0 0       0 if ($dbi->connect->err) {
494 0         0 $self->error(sprintf("Can't delete record: %s", uv2null($dbi->connect->errstr)));
495 0         0 return 0;
496             }
497 0         0 return 1;
498             }
499              
500             # Queue methods
501              
502             sub enqueue { # Set STATUS_NEW
503 1     1 1 2 my $self = shift;
504 1         8 my ($to, $ch_name, $ch_attr, $subject, $message) =
505             read_attributes([
506             [qw/TO USER USERNAME RECIPIENT/],
507             [qw/NAME CHANNEL CH_NAME/],
508             [qw/ATTR ATTRS ATTRIBUTES CH_ATTR CH_ATTRS/],
509             [qw/SUBJECT SUBJ SBJ/],
510             [qw/MESSAGE MSG/],
511             ], @_);
512 1 50       120 return 0 unless $self->ping;
513 1         33 $self->error("");
514 1         2 my $dbi = $self->{dbi};
515              
516             # Add new record
517 1         2 my $now = time();
518 1         9 my $json = $self->serializer->serialize($ch_attr);
519 1 50       210 unless ($self->serializer->status) {
520 0         0 $self->error(sprintf("Can't serialize channel attributes: %s", uv2null($self->serializer->error)));
521 0         0 return 0;
522             }
523              
524             # Add new record
525             $dbi->execute(MONOTIFIER_ADD,
526             $to, $ch_name, $subject, encode_base64($message), $json,
527             $now, # published
528             $now, # scheduled
529 1         43 ($now + $self->{expires}), # expired
530             undef, # sent
531             0, # attempt
532             STATUS_NEW, # status
533             undef, # errcode
534             undef, # errmsg
535             );
536 1 50       10495 if ($dbi->connect->err) {
537 0         0 $self->error(sprintf("Can't insert new record: %s", uv2null($dbi->connect->errstr)));
538 0         0 return 0;
539             }
540              
541             # Get ID
542             my $id = $self->{issqlite}
543 1 50       14 ? $dbi->connect->sqlite_last_insert_rowid()
544             : $dbi->connect->last_insert_id();
545              
546 1   50     11 return $id || 0;
547             }
548             sub retrieve { # Set STATUS_BUSY
549 1     1 1 2 my $self = shift;
550 1         4 my ($status) =
551             read_attributes([
552             [qw/STATUS REQUIRE REQ/],
553             ], @_);
554 1 50       12 return unless $self->ping;
555 1         28 $self->error("");
556 1         2 my $dbi = $self->{dbi};
557              
558             # status == ? || STATUS_FAIL; scheduled <= now();
559 1         1 my $now = time();
560 1   50     7 my %rec = $dbi->recordh(MONOTIFIER_GET_NEXT, $now, $status || STATUS_FAIL);
561 1 50       318 if ($dbi->connect->err) {
562 0         0 $self->error(sprintf("Can't get record: %s", uv2null($dbi->connect->errstr)));
563 0         0 return;
564             }
565 1 50       19 return unless %rec;
566              
567             # Set status to STATUS_BUSY
568 1   50     30 my $attempt = $rec{attempt} || 0;
569             $dbi->execute(MONOTIFIER_UPDATE_STATUS,
570             STATUS_BUSY, # status
571             $now + _sheduled_calc($attempt), # scheduled
572             undef, # sent
573             ++$attempt, # attempt (new)
574             undef, # errcode
575             undef, # errmsg
576 1   50     4 $rec{id} || 0
577             );
578 1 50       8397 if ($dbi->connect->err) {
579 0         0 $self->error(sprintf("Can't change status: %s", uv2null($dbi->connect->errstr)));
580 0         0 return;
581             }
582              
583 1 50 33     16 if (defined($rec{message}) && length($rec{message})) {
584 1         6 $rec{message} = decode_base64($rec{message});
585             }
586 1 50 33     16 if (defined($rec{attributes}) && length($rec{attributes})) {
587 1         4 $rec{attributes} = $self->serializer->deserialize($rec{attributes});
588 1 50       231 unless ($self->serializer->status) {
589 0         0 $self->error(sprintf("Can't deserialize channel attributes: %s", uv2null($self->serializer->error)));
590 0         0 return;
591             }
592             }
593              
594 1         16 return {%rec};
595             }
596             sub requeue { # Set STATUS_FAIL
597 1     1 1 1 my $self = shift;
598 1         6 my ($id, $code, $error) =
599             read_attributes([
600             [qw/ID/],
601             [qw/CODE ERRCODEE ERR_CODE/],
602             [qw/ERROR ERRMESSAGE ERRMSG ERR_MESSAGE ERR_MSG/],
603             ], @_);
604 1 50       61 return 0 unless $self->ping;
605 1         30 $self->error("");
606 1         2 my $dbi = $self->{dbi};
607              
608             # Set status
609 1   50     4 $dbi->execute(MONOTIFIER_UPDATE_ERROR,
610             STATUS_FAIL, # status
611             $code, # errcode
612             $error, # errmsg
613             $id || 0
614             );
615 1 50       8088 if ($dbi->connect->err) {
616 0         0 $self->error(sprintf("Can't update record: %s", uv2null($dbi->connect->errstr)));
617 0         0 return 0;
618             }
619              
620 1         16 return 1;
621             }
622             sub dequeue { # Set STATUS_SENT
623 1     1 1 2 my $self = shift;
624 1         4 my ($id) =
625             read_attributes([
626             [qw/ID/],
627             ], @_);
628 1 50       32 return 0 unless $self->ping;
629 1         30 $self->error("");
630 1         1 my $dbi = $self->{dbi};
631              
632             # Set status to STATUS_SENT
633 1   50     5 $dbi->execute(MONOTIFIER_UPDATE_STATUS,
634             STATUS_SENT, # status
635             undef, # scheduled
636             time(), # sent
637             0, # attempt
638             undef, # errcode
639             undef, # errmsg
640             $id || 0
641             );
642 1 50       8017 if ($dbi->connect->err) {
643 0         0 $self->error(sprintf("Can't change status: %s", uv2null($dbi->connect->errstr)));
644 0         0 return;
645             }
646              
647 1         13 return $id;
648             }
649             sub cleanup { # Delete too old records by expired field
650 1     1 1 2 my $self = shift;
651 1 50       3 return 0 unless $self->ping;
652 1         29 $self->error("");
653 1         2 my $dbi = $self->{dbi};
654              
655             # CleanUp (by expired)
656 1         2 my $now = time();
657 1         4 $dbi->execute(MONOTIFIER_CLEANUP, $now);
658 1 50       183 if ($dbi->connect->err) {
659 0         0 $self->error(sprintf("Can't delete records (cleanup): %s", uv2null($dbi->connect->errstr)));
660 0         0 return 0;
661             }
662              
663             # CleanUp (by maxtime)
664 1   50     25 my $maxtime = $self->{maxtime} || MAXTIME;
665 1         5 $dbi->execute(MONOTIFIER_FLUSH,
666             STATUS_FAIL, # status
667             255, # errcode (Cleanup level)
668             "Sending the message is taking too long!", # errmsg
669             STATUS_BUSY, STATUS_NEW,
670             $now - $maxtime,
671             );
672 1 50       197 if ($dbi->connect->err) {
673 0         0 $self->error(sprintf("Can't update records (cleanup): %s", uv2null($dbi->connect->errstr)));
674 0         0 return 0;
675             }
676              
677 1         11 return 1;
678             }
679             sub purge {
680 1     1 1 2 my $self = shift;
681 1 50       3 return 0 unless $self->ping;
682 1         27 $self->error("");
683 1         1 my $dbi = $self->{dbi};
684              
685 1         4 $dbi->execute(MONOTIFIER_PURGE);
686 1 50       7960 if ($dbi->connect->err) {
687 0         0 $self->error(sprintf("Can't purge table: %s", uv2null($dbi->connect->errstr)));
688 0         0 return 0;
689             }
690 1         14 return 1;
691             }
692              
693             sub _sheduled_calc {
694 1     1   2 my $t = shift; # Attempt number
695 1 50 33     5 if ($t >= 0 and $t < 5) { return 60 } # 1 min per 5 min (5 times)
  1 0 0     6  
    0 0        
    0 0        
    0 0        
    0 0        
696 0           elsif ($t >= 5 and $t < 7) { return 60*5 } # 5 min per 15 min (2 times)
697 0           elsif ($t >= 7 and $t < 10) { return 60*15 } # 15 min per 1 hour (3 times)
698 0           elsif ($t >= 10 and $t < 33) { return 60*60 } # 1 hour per day (23 times)
699 0           elsif ($t >= 33 and $t < 39) { return 60*60*24 } # 1 day per week (6 times)
700 0           elsif ($t >= 39 and $t < 42) { return 60*60*24*7 } # 1 week per month (3 times)
701 0           return 60*60*24*30; # every 1 month
702             }
703              
704             1;
705              
706             __END__