Overview | Index by: file name |
procedure name |
procedure call |
annotation
storage.tcl
(annotations | original source)
#
# Copyright (C) 2008 Alexandros Stergiakis <sterg@kth.se>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#//#
# Persistent storage across reboots. It relies on distribution-specific event handlers that
# will copy the data to persistent storage, except if the STORAGE_FILE already resides in
# a persistent directory. File is always restored on boot. Data are accessed as an array.
#
# We refer to this persistent storage as Storage. The Storage is appropriate for information
# that are not suitable for the main conf, such as time of last log-in, reason of last reboot,
# log-in history, failed login attempts, and other casual information that are not part of
# the router configuration as such.
#
# Warning:
# Notice that this Storage facility is only for the Master Interpreter/Thread. It is not meant
# to be used for concurrent use by Master and Session threads/interp.
#
# @changelog
# *
#
# @copyright 2007-2008 Alexandros Stergiakis <alsterg@gmail.com>
# @author Alexandros Stergiakis <alsterg@gmail.com>
#//#
namespace eval storage {
namespace import ::helper::writefile ::helper::readfile
namespace export load unload
# Global:
array set ::Storage {}
variable loaded 0
variable lastjob 0
# Invoked with a trace when-ever Storage is modified.
# @assume storage::load is executed before.
proc update {args} {
global Storage
variable lastjob
if {[catch {after info $lastjob}]} { ;# No pending job
Global STORAGE_FILE
# XXX Use mmap (remove trace)
writefile $STORAGE_FILE [array get Storage]
# Emitted after persistent storage gets modified. This event is rate limitted.
set lastjob [after 10000 [list event emit PERSISTENT_STORAGE_UPDATE]] ;# (@magic-number)
# A handler attached to this event can be used to take care of copying the
# Storage File (STORAGE_FILE) to a safe place after a modification is done.
# It can also be used to monitor specific variables within Storage.
}
}
# Loads stored information from last boot in the global namespace as an array named "Storage".
# Access to the Storage array can then be done as usual with the "global" command.
proc load {} {
global Storage
variable loaded
variable lastjob
if {$loaded} { return }
Global STORAGE_FILE
array set Storage [readfile $STORAGE_FILE]
set loaded 1
# Note: Write variable trace is called after the variable/array is modified
trace add variable ::Storage write ::storage::update
}
# Unloads Storage from the global namespace and invokes "update" to save it.
# Access with the "global" command will not be possible after this.
proc unload {} {
global Storage
variable loaded
variable lastjob
if {! $loaded} { return }
if {! [catch {after info $lastjob}]} { ;# Pending job
after cancel $lastjob
event emit PERSISTENT_STORAGE_UPDATE
}
set lastjob 0
trace remove variable ::Storage write ::storage::update
unset Storage
set loaded 0
}
namespace ensemble create
} ;# End of Namespace
Overview | Index by: file name |
procedure name |
procedure call |
annotation
File generated 2010-03-13 at 22:28.