Hi Sue, Your analysis is correct. There is always a tiny probability in the current system of a mismatch between the writer and the reader. Your suggestion of an option in TTree::AutoSave to keep more than one cycle will only be a marginal improvement. It is easy to implement what you suggest by not calling AutoSave, but implementing yourself the 3 or 4 lines of code to do this job (have a look at AutoSave). There are two possible solutions to this problem using semaphores via shared memory or an intermediate lock file. I do not think that the solution via shared memory is very attractive in new DAQs where probably the writer and reader are on different machines. I could implement the following algorithm; When the writer needs to update the directory (add/remove a key), it creates first a lock file (name =filename.lock) and deletes this file when the operation is terminated. When the reader calls ReadKeys, this function checks if the lock file exists. If not it can go ahead, else it waits (using a TTimer). A completly safe solution would imply a lockWrite file by the writer and a lockRead file by the reader. As usual comments are welcome. Rene Brun Susan Kasahara wrote: > > Hi ROOTers, > I am using TTree::AutoSave in an online context such that a DAQ process fills event data into a > TTree and AutoSave's the TTree to file at regular intervals. A separate Dispatcher process retrieves the > latest TTree from the DAQ file (while the file is still open and data is still being written to it by the DAQ), > and serves the data to various client applications. > This setup works in general, however I am concerned about potential collisions between the DAQ & > Dispatcher that may occur if the Dispatcher should happen to be attempting to access the latest Tree > from the file just as the DAQ is Autosave'ing a new TTree (and deleting the old TTree). > The potential collision sequence is: > > DAQ | Dispatcher > ------------------------------------------------------------------------ > | (1) gDirectory -> ReadKeys(); > | // The dispatcher reads the latest set of keys from > | // file in preparation to read latest TTree > (2) tree -> AutoSave(); | > // the DAQ autosave's the latest TTree, | > // and automatically deletes the previous | > // TTree. | > | (3) tree = (TTree*)gDirectory -> Get("MyTree"); > | // the dispatcher attempts to access the DAQ > | // Tree with Keys that are now stale (due to the > | // DAQ's ill-timed AutoSave) and crashes. > gDirectory -> SaveSelf(); | > // the DAQ updates the directory keys to | > // point to the latest TTree. | > > This sequence has an admittedly small probability of occuring, but it is important for > me to cover it because of the online setting. > One simple solution to this that I can think of, that avoids the use of a lock file, is to > modify TTree::AutoSave to include an option to *not* automatically delete the previous TTree. > This will allow me to keep two TTree headers on disk so that even "stale" keys point to > something reasonable. > I could then handle the purging of older TTree's outside of AutoSave using the > TDirectory::Purge() method or delete them directly. > Would it be difficult to implement this option to not automatically delete old TTree's > in TTree::AutoSave, or do you have any advice on how to handle this better? > Thanks in advance for your help, > Sue Kasahara
This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:35 MET