[REBOL] File Locking (flocking)? Re:
From: deadzaphod:hotma:il at: 8-Oct-2000 9:10
>Subject: [REBOL] File Locking (flocking)?
>Date: Sun, 8 Oct 2000 3:49:15 -0500
>
>Anyone have any experience with this?
>
>Need to lock some files which can be accessed by multiple users at once,
>need to flock to maintain data integrity.
unfortunatly rebol does not have built-in support for file locking.
However, I've found a couple of methods that seem to work: the easiest is to
use functions like this
try-get-filelock: func [ file ] [ not error? try [ make-dir rejoin [
%file-lock- file "/" ] ] ]
free-filelock: func [ file ] [ delete rejoin [ %file-lock- file "/" ]
return ]
get-filelock: func [ file retries /local retry ] [
retry: 0
while [not try-get-filelock file] [
wait 0.5
if (retry: retry + 1) > retries [ return false ]
]
return true
]
and obtain the lock with a line something like this:
if not get-filelock %msgboard.txt 40 [ print "---error---" quit ]
possibly with extra code to email you notification when locking fails (in
case an unattended script crashed without unlocking things).
another alternative is to set up a server to handle requests for locks, and
have the program query the server to lock files. an example of how to do
this is provided below if you want to try that approach.
REBOL [
Title: "REBOL Locking System"
Date: 23-June-1999
File: %locker.r
Author: "Cal Dixon"
Email: [deadzaphod--hotmail--com]
Version: 1.1
Purpose: "To provide functions for voluntary resource locking in
rebol"
Rights: {
Copyright (c) 1999 Caleb Dixon. This version is free for ANY
use.
Do whatever you want with it as long as you don't claim to
have created this.
}
Note: {
Be sure to run the 'lock-server function in a separate rebol
process before
calling the other functions, they will fail if the server is
not available.
Once the server is running, you can just "do %locker.r" then
use 'get-lock and
'free-lock in any script that needs resource locking.
}
Comment: "This version does not do enough error checking. This will
be fixed later."
]
; change this line if you want to use a port other than 7007 for this
service.
if not value? 'rebol-lock-port [rebol-lock-port: 7007]
lock-server: function [ {Handles requests to lock and unlock named
resources.} ] [] [
locks: make block! []
version: 1
listener: open/lines join tcp://: rebol-lock-port
while [true] [
while [true] [
conn: first listener
wait conn
if error? try [ req: load first conn ] [ req: "ERROR" ]
if all [ (block? req) (>= (length? req) 2 ) ] [ break ]
close conn
]
probe req
if (= to-lit-word (pick req 1) 'lock) [
if none? find locks (pick req 2) [ append locks reduce [ (pick req
2) true ] ]
if (available: do rejoin [ "locks/" (pick req 2) ]) [
do rejoin [ "locks/" (pick req 2) ": false" ]
]
insert conn rejoin [ "[" available "]" ]
]
if (= to-lit-word (pick req 1) 'free) [
do rejoin [ "locks/" (pick req 2) ": true" ]
insert conn "[ true ]"
]
if (= to-lit-word (pick req 1) 'version) [
insert conn rejoin [ "[ " (>= version (pick req 2)) " ]" ]
]
close conn
] ;end while loop
] ;end lock-server function
try-obtain-lock: function [ "Attempt to lock a named resource"
whichword [word!] /server "Use specific lockserver instead of
localhost:7007"
servname [url!] "Address of lockserver" ] [ conn r ] [
either server [
conn: open/lines servname
] [
conn: open/lines join tcp://localhost: rebol-lock-port
]
insert conn rejoin [ "[lock " whichword "]" ]
r: do load first conn
close conn
return r
]
get-lock: function [ "Attempt to lock a named resource, and retry if it is
not available"
whichword [word!] retries [integer!]
/server "Use specific lockserver instead of localhost:7007"
servname [url!] "Address of lockserver" ] [ gotit ] [
either server [
while [ not (gotit: try-obtain-lock/server whichword servname) ] [
if (retries < 1) [ return gotit ]
retries: retries - 1
wait 1
]
] [
while [ not (gotit: try-obtain-lock whichword) ] [
if (retries < 1) [ return gotit ]
retries: retries - 1
wait 1
]
]
gotit
]
free-lock: function [ "Free a named resource" whichword [word!]
/server "Use specific lockserver instead of localhost:7007"
servname [url!] "Address of lockserver" ] [ conn r ] [
either server [
conn: open/lines servname
] [
conn: open/lines join tcp://localhost: rebol-lock-port
]
insert conn rejoin [ "[free " whichword "]" ]
r: do load first conn
close conn
return r
]
check-lock-server: function [ "Check for the presence of a usable
lock-server"
/server "Use specific lockserver instead of localhost:7007"
servname [url!] "Address of lockserver"] [ conn versionok ] [
either server [
if error? try [ conn: open/lines servname ] [ return false ]
] [
if error? try [ conn: open/lines join tcp://localhost: rebol-lock-port
] [ return false ]
]
insert conn "[version 1]"
if error? try [ versionok: do load first conn ] [ return false ]
close conn
return versionok
]
_________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com.
Share information about yourself, create your own public profile at
http://profiles.msn.com.