CallBackery
view release on metacpan or search on metacpan
0.58.3 2026-07-30 16:11:29 +0200 Tobias Oetiker <tobi@oetiker.ch>
- Config: restoring a configuration blob replaced the configuration
database file, giving it a new inode. Every connection open at the
time stayed attached to the old, now unlinked file: it went on
reading the pre-restore configuration and failed on its first write
with SQLITE_READONLY_DBMOVED, which SQLite reports as "attempt to
write a readonly database". With a prefork server and background
helpers that is most of the processes on the machine. The
replacement database is now built beside the live one and copied in
with SQLite's online backup API, so the inode is preserved and open
connections simply see the restored data. If the write lock cannot
be had within 30 seconds the restore now gives up with an error and
leaves the database untouched, rather than restoring it half way.
0.58.2 2026-07-20 12:54:27 +0200 Tobias Oetiker <tobi@oetiker.ch>
- Frontend ui.plugin.Form: make sure trigger load does not overwrite
fix for automated testing which fills forms very quickly
0.58.1 2026-07-16 08:39:18 +0200 Tobias Oetiker <tobi@oetiker.ch>
see Song.pm for example
* 121c4ab - (HEAD -> login-log) log login acctivity (4 minutes ago) <Tobias Oetiker>
* bf1b222 - (origin/master, origin/HEAD, master) fix generator to work with mojo8 (3 months ago) <Tobias Oetiker>
* 4087cfe - trying to get travis going again (3 months ago) <Tobias Oetiker>
* fc77dca - fix some regressions (3 months ago) <Tobias Oetiker>
* 7c715da - fix userform syntax (3 months ago) <Tobias Oetiker>
* dc01dcb - teach Promises to callbackery (3 months ago) <Tobias Oetiker>
* 35bcb56 - 0.13.8 (8 months ago) <Tobias Oetiker>
* f0cb691 - remove stray 0 at the end of the sqlite dump (8 months ago) <Tobias Oetiker>
* 043a79c - (tag: v0.13.7) use database dump in the backup file not the raw db file (8 months ago) <Tobias Oetiker>
* 6dc7875 - (tag: v0.13.4) fix spelling of instanciation ... it is instantiation (8 months ago) <Tobias Oetiker>
* 60c4ec8 - (tag: v0.13.3) must load CallBackery::User (9 months ago) <Tobias Oetiker>
* 2fad13b - (tag: v0.13.2) limit width of note column in forms (9 months ago) <Tobias Oetiker>
* a732cd7 - (tag: v0.13.1) fix call to userObject (9 months ago) <Tobias Oetiker>
* 4878b5b - (tag: v0.13.0) Fighting circular references (9 months ago) <Tobias Oetiker>
* 7547c30 - update PERL_MODULES (10 months ago) <Tobias Oetiker>
* 7d871b9 - (tag: v0.12.9) fix deprecated route syuntax (no more braces) (10 months ago) <Tobias Oetiker>
* d22bf7e - update template PERL_MODULES (10 months ago) <Tobias Oetiker>
* 36e18d1 - (tag: v0.12.8) updated dependncy to require latest qooxdoo plugin (10 months ago) <Tobias Oetiker>
* 71ba760 - widen tests (10 months ago) <Tobias Oetiker>
lib/CallBackery/Config.pm view on Meta::CPAN
my $crypt = $self->getCrypt($password);
return $crypt->encrypt($self->pack16($zipData));
}
# how long to keep trying when someone else holds a lock on the config
# database; package scoped so that tests can shorten it
our $RESTORE_BUSY_TIMEOUT_MS = 30_000;
# Build a replacement config database with $builder and then copy it over the
# live one with SQLite's online backup API, so that the database keeps its
# inode.
#
# Replacing the file instead (the way this used to work) leaves every long
# lived handle in the system attached to the old, now unlinked inode: the
# config daemon and its workers, the application server, and any helper that
# happens to be running at the time. Those handles go on reading stale
# configuration and fail on their first write with SQLITE_READONLY_DBMOVED,
# which SQLite reports as "attempt to write a readonly database".
#
# The staging database lives next to the config database rather than in a
lib/CallBackery/Config.pm view on Meta::CPAN
no autodie;
unlink glob $staging.'*';
use autodie;
$builder->($staging);
chmod 0600, $staging;
my $dbh = DBI->connect("dbi:SQLite:dbname=$cfgDb",'','',{
RaiseError => 1,
PrintError => 0,
AutoCommit => 1,
});
# the backup runs the destination's busy handler while it waits for
# the write lock; on top of that we retry, because a backup that
# starts while another connection sits in a read transaction gives up
# rather than waiting
$dbh->sqlite_busy_timeout($RESTORE_BUSY_TIMEOUT_MS);
my $deadline = Time::HiRes::time() + $RESTORE_BUSY_TIMEOUT_MS / 1000;
my ($busy,$tries) = (undef,0);
while (1) {
$busy = undef;
last if eval { $dbh->sqlite_backup_from_file($staging) };
$busy = $@ || $dbh->errstr || 'unknown error';
last if Time::HiRes::time() >= $deadline;
# first attempt and then roughly every five seconds, so that a
# long wait is visible without a log line per retry
$self->log->warn("Config database busy, retrying restore: $busy")
if $tries++ % 50 == 0;
Time::HiRes::sleep(0.1);
}
$dbh->disconnect;
# giving up here is safe: the live database has not been touched, so
lib/CallBackery/GuiPlugin/Abstract.pm view on Meta::CPAN
=cut
has mayAnonymous => sub {
return 0;
};
=head2 stateFiles
A list of files that contain the state of the settings configured by
this plugin this is used both for backup purposes and to replicate the
settings to a second installation.
=cut
has stateFiles => sub {
[];
};
=head2 unconfigureFiles
lib/CallBackery/User.pm view on Meta::CPAN
has log => sub ($self) {
$self->controller ? $self->controller->log : $self->app->log;
}, weak => 1;
=head2 $self->userId
By default the userId is numeric and represents a user account. For system tasks, it gets set to alphabetic identifiers.
The following alphabetic identifiers do exist:
__CONSOLE when running in the config console mode
__CONFIG for backup and restore tasks
=cut
=head2 userId
return the user id if the session user is valid.
( run in 2.710 seconds using v1.01-cache-2.11-cpan-c221a9de4ec )