>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:      [EMAIL PROTECTED]
   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.

Reply via email to