Announcement

Collapse
No announcement yet.

Multi-User Programming

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Multi-User Programming

    Two questions about MCM’s article
    Fundamentals of Multi-User Programming in PowerBASIC

    1. MCM describes two forms of record locking: physical and logical. In physical locking the network O/S locks the record (per program command). The lock is detected by other users when they try to access the record and get an Error. In logical locking each record has an extra one byte field. The program sets this to “L” to lock the record. Other users check this byte to determine when the record is locked.

    Question: In logical locking if the “locker” user terminates abnormally his lock stays in place. In case a lock gets stuck like that, as pointed out in MCM’s article, there needs to be an administrative way of removing locks. How about physical locks: what happens to a physical lock if the computer of the user who set it crashes? If the lock stays (for any great length of time) how would another program remove it?

    Question: Why provide two different methods of locking records? What are the advantages and disadvantages of each?

    2. Per MCM’s article, the data file, say Customer.txt, is opened with

    OPEN "Customer.txt" FOR RANDOM ACCESS READ WRITE LOCK SHARED AS CustFileNo LEN = LEN(DataRecord)

    When is the file open and closed? Can the program open it when the user starts the program and close it only when the user closes the program, keeping the file open all day long? (After all, it’s SHARED.) Or should the program, each time a user wants to access a record, open the file then close it right after the user is done with the record?

    MCM’s example code just does one edit of a given record, but you could put a do-loop around it. So the above question is: put OPEN before DO and CLOSE after LOOP, or OPEN after DO and CLOSE before LOOP ?

    End of questions.

    MCM’s example code doesn’t check if the record got changed by someone else while the user was typing. This check has been added in a new version of MCM’s code below. If another user had changed the field by the time he tries to save his work, he gets a message that it cannot be saved. (Of course that situation could be handled another way.) Other changes include:
    1. PBCC instead of PBDOS.
    2. A loop so you can edit several records without restarting the program.
    3. A more persistent GET, trying several times each fifth of a second instead of just twice after half a second.
    4. Closing the file. (MCM’s original code is missing a CLOSE statement.)

    I put OPEN outside the do-loop.
    Code:
    ' MULTIA.bas
    ' Bare-bones multiuser customer file maintenance.
    ' Original PDOS by Michael Mattias, October 1995.
    ' Here converted to PBCC with minor improvements.
    
    #Compile Exe
    #Dim All
    '------------------------------------------------------------------
    
    ' Constants
    
    %PhysicalLocking  = -1                  'true (compiler option)
    %LogicalLocking   = Not %PhysicalLocking
    %PermissionDenied = 70                  'error code
    '------------------------------------------------------------------
    
    Type CustomerRecord              ' three fields, not counting AcctNo & Record Status
      AcctNo        As Long
      AcctName      As String * 30
      StreetAddress As String * 30
      CityStateZip  As String * 30
      RecordStatus  As String * 1    ' used if %LogicalLocking: "L" or " "
    End Type
    '------------------------------------------------------------------
    
     Global ReadDelay  As Single
     Global CustFileNo As Long
    '==================================================================
    
    ' The general purpose subroutines from here to the next double line
    ' separator could be placed in an include file.
    
    ' Read a record, test if locked.
    Sub ReadCustomerRecord (RecordNo As Long, DataRecord As CustomerRecord, Stat As Long)
     Local count As Long
     On Error Resume Next
    
     count = 0
     Do
       Stat = 0
       ErrClear
       Incr count
       Get CustFileNo, RecordNo, DataRecord
       Stat = Err                                     ' record the error
    
       If Stat = 0 _                                  ' good read
         And  %LogicalLocking _                       ' logical locking
         And  DataRecord.RecordStatus = "L" Then      ' locked by another user
         Stat = %PermissionDenied
       End If
    
       If Stat = %PermissionDenied Then               ' wait and retry
         Sleep ReadDelay
       End If
     Loop Until stat = 0 Or count > 3
    
     ' now Stat contains success (0) or failure.
    End Sub
    '------------------------------------------------------------------
    
    ' Lock a record.
    Sub LockCustomerRecord (RecordNo As Long, Stat As Long)
     Local ReadStatus As Long
     Local DataRecord As CustomerRecord
    
     On Error Resume Next
    
      If %PhysicalLocking Then        ' use PB and O/S services
        Lock CustFileNo, RecordNo
        Stat = Err
      Else
        ReadCustomerRecord RecordNo, DataRecord, ReadStatus
        ' get current copy of the record
        If ReadStatus Then            ' some error in the read - maybe locked!
          Stat = ReadStatus           ' return it to the main program
        Else
          DataRecord.RecordStatus = "L"         ' mark the disk record "locked"
          Put CustFileNo, RecordNo, DataRecord  ' and store it
          Stat = Err                            ' could get error on PUT!
        End If
      End If
    End Sub
    '------------------------------------------------------------------
    
    ' Unlock a Record.
    Sub UnlockCustomerRecord (RecordNo As Long, Stat As Long)
      Dim DataRecord As CustomerRecord
    
      On Error Resume Next
    
      If %PhysicalLocking Then                   ' use PB and O/S services
        UnLock CustFileNo, RecordNo
        Stat = Err
      Else
        ReadCustomerRecord RecordNo, DataRecord, Stat
        If Stat = 0 Then
          DataRecord.RecordStatus = " "          ' clear out the "L"
          Put CustFileNo, RecordNo, DataRecord
          Stat = Err
        End If
      End If
    End Sub
    '==================================================================
    
    Function PBMain
     Local DataRecord As CustomerRecord
     Local SaveRecord As CustomerRecord   ' not used here
     Local CustNum As Long
     Local Stat As Long                   ' error code
     Local NewAcctName As String
    
     Print " Records are identified by Customer number,"
     Print " starting at 1.  Each record has three fields,"
     Print " but here you can only update one of them:"
     Print " AcctName."
     Print
    
     ReadDelay = .2                       ' global constant, in seconds
    
     CustFileNo = FreeFile                ' global constant
    
     Open "Customer.txt" For Random Access Read Write Lock Shared _
        As CustFileNo Len = Len(DataRecord)
    
     Do                                   ' loop through given customer numbers
    
       Input " Enter Customer Number to view/update ", CustNum
       If CustNum = 0 Then Exit Do
    
       ' read it
       ReadCustomerRecord Custnum, DataRecord, Stat
    
       If     Stat = %PermissionDenied Then
    
         ' this will never happen using instances of this program,
         ' but it might happen in a version that had to lock the
         ' whole file for a time
         Print " Can't update this customer - record in use"
    
       ElseIf Stat <> 0 Then
    
         Print " Error on GET, # "; Stat
    
       Else
    
         Print " AcctName:      "; DataRecord.AcctName
         Print " StreetAddress: "; DataRecord.StreetAddress
         Print " CityStateZip:  "; DataRecord.CityStateZip
         Print
    
         ' save the image used by operator
         SaveRecord = DataRecord
    
         ' get the new data from the user
    
         Line Input " Enter new AcctName: ", NewAcctName
    
         If NewAcctName = "" Then Iterate Do
    
        ' lock the record
         LockCustomerRecord CustNum, Stat
    
        ' get a current copy of it
         If Not Stat Then
           ReadCustomerRecord Custnum, DataRecord, Stat
         End If
    
        ' check if this is the same as it was when we started
    
         If Not Stat Then                       ' OK on the LOCK and READ
           If DataRecord.AcctName = SaveRecord.AcctName Then
            ' store the record back to disk with new data
            DataRecord.AcctName = NewAcctName
            Put CustFileNo, CustNum, DataRecord
            ' unlock the record
            UnlockCustomerRecord CustNum, Stat
            ' tell user successful
            Print " Customer file updated."
           Else
            ' unlock the record
            UnlockCustomerRecord CustNum, Stat
            ' tell user he didn't type fast enough
            Print " Someone else edited this record while you were typing."
           End If
         End If
    
         If Stat Then
          Print " Error on file access."
         End If
    
         Print
    
       End If
    
     Loop
    
     Close CustFileNo
    End Function
    Last edited by Mark Hunter; 5 Oct 2009, 01:27 AM.
    Algorithms - interesting mathematical techniques with program code included.

    #2
    >Closing the file. (MCM’s original code is missing a CLOSE statement.)

    You are the first to notice in this in fourteen years. That breaks - nay, it shatters my previous record, which was a paltry nine years from release to discovery of an error.


    As to when you "should" open and close the file, that's pretty much a personal preference. In the Windows era, however, I uniformly recommend a file never be left open across notification messages.

    That is, a 'read' is performed as 'open,read, close'; a 'save' as 'open, write, close,' etc.

    (All that said, I really do get a kick out of seeing something that old still in service. It's the kind of thing which keeps me goin.')

    MCM
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


      #3
      MCM,

      Your article is very helpful.

      Everybody,

      Regarding physical locking: PBCC Help states “All locked records ... must be unlocked ... before the file can be closed.” VB Help tells you to “... remove all locks ... before closing a file or quitting your program. Failure to remove locks produces unpredictable results.”

      Eventually someone’s PC is going to shutdown abnormally. Pretty quickly the server will know the PC isn’t there anymore. Does the server automatically remove any locks, or do they stay in place? If they stay in place, how can you remove them?

      I don’t have my own network but I can run two instances of the same program on my single PC. If I use one instance to lock a record of a file, then exit that instance without unlocking the record or closing the file (unless exiting the program does that automatically), I’ve found that the other instance can access the record (read and write).

      But two PCs accessing a file on a server might work differently.

      Maybe this is the advantage of logical locking versus the above physical locking: the programmer has complete control. If a PC does crash with a (logical) lock in place, though it’s going to stay there at least you know the situation and how to remove it.
      Algorithms - interesting mathematical techniques with program code included.

      Comment


        #4
        "IF" PowerBASIC implements the LOCK statement via the LockFile Windows' API function....

        If a process terminates with a portion of a file locked or closes a file that has outstanding locks, the locks are unlocked by the operating system.
        Unfortunately the PB/WIN help file, under LOCK, does NOT say either "how implemented" or "what happens if..." These sound like they would be good additions to same.

        I remember that "I didn't unlock" problem back in MS-DOS (fix: press Ctrl and Alt and Delete simultaneously) , but I have never seen it under Windows.

        MCM
        Last edited by Michael Mattias; 5 Oct 2009, 05:12 PM.
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


          #5
          I always liked the idea of using another file to control
          who has the ball.

          This also means you can open your database in any way you like for performance or other reasons, such as backup.

          I am like MCM in not keeping any data files open. It is much safer with little perfoemance loss bc there is file caching.
          Also there is a lot of file buffering taking place Between you and networks.

          Opportunistic file locking can be a big issue too.

          You can also do the thing where a file is created and left open for other programs to see until you close it, your program ends or your computer crashes then the file disappears. I like using that idea as a file locking method. It works well
          in batch file processing too
          Last edited by Paul Purvis; 6 Oct 2009, 10:48 AM.
          p purvis

          Comment


            #6
            Rather than file locking I normally use the standard record locking. Yes there were some problems opportunistic locking back in early 98, NT4 days haven't experienced a problem since then.
            The advantage of record locking over file locking is that the file can be backed up even if a user goes home and leaves a using program open (so long as the program isn't badly written to hold a lock on a record).
            MS uses a variation in that they lock pages usually 4K via the standard method. Whilst this is more efficient it can cause the dreaded deadlock.

            Comment


              #7
              Multi-user software should NEVER lock the entire FILE under 'normal operating conditions'; it should only lock the RECORD(s) to be updated.

              >so long as the program isn't badly written to ....

              Um, 'badly written' takes ALL bets off the table.
              Michael Mattias
              Tal Systems (retired)
              Port Washington WI USA
              [email protected]
              http://www.talsystems.com

              Comment


                #8
                Awhile back, we use Lantastic for all our networking needs and on a dos server, we even had the file sharing part of the server turned off. You could still share files, just no locking, file or record and on the windows server(a workstation, peer to peer file sharing, and no dedicated server operating system). Today, with newer software, we use linux dedicated servers.

                I ran some dbase II or III stuff for just a short time and it had some kind of built in record locking and i never did find out how they where accomplishing the task of doing it on a dos server without the SHARE command being used typically from inside the autoexec.bat file. Maybe somebody has knowledge on what Aston Tate was doing with dbase to get the record locking accomplished.

                If you are going to put a marker inside the record of a file and leave the file in a opened state, do not forget to flush your file buffers. This is where i believe not keeping the file opened can be useful, bc if you close the file, hopefully all the file buffers are written to disk. And who knows what is coming down the pipe from microsoft in future years.
                p purvis

                Comment


                  #9
                  Paul,

                  I always liked the idea of using another file to control who has the ball.
                  I can only guess your meaning.

                  To logically lock a data file you could create a tiny file with your user’s network ID in it. You delete the tiny file to unlock the data file. The existence of this tiny file indicates to other users that the data file is locked, and it also tells by whom. If so, what would be the advantage of that versus using one throw-away (non-data) record at the beginning of the data file to indicate lock status? Or you mean something else?

                  Opportunistic file locking can be a big issue too.
                  What makes a lock opportunistic?

                  You can also do the thing where a file is created and left open for other programs to see until you close it, your program ends or your computer crashes then the file disappears.
                  Is that true? On a single PC, if a program creates a file with OPEN, then before closing abnormally terminates, the file remains.
                  Last edited by Mark Hunter; 7 Oct 2009, 05:25 PM.
                  Algorithms - interesting mathematical techniques with program code included.

                  Comment


                    #10
                    What makes a lock opportunistic?
                    Google "opportunistic locking" and review the MS citations. This term refers to a system setting that affects how servers behave when clients request locks. It's a mistake to assume that the server will immediately lock a file or record in all cases.

                    Comment


                      #11
                      >>I always liked the idea of using another file to control who has the ball.

                      >I can only guess your meaning

                      Basically it means, you use another file to tell you "the master is file is in use." It can be done by file content (although that now gets into its own integrity issues), or its existence.

                      I personally never liked this and never used it. For that matter, I never liked 'logical' locks and never used those either, except for demonstration and testing.

                      MCM
                      Michael Mattias
                      Tal Systems (retired)
                      Port Washington WI USA
                      [email protected]
                      http://www.talsystems.com

                      Comment


                        #12
                        Record track and trace thought

                        Can't you just briefly lock the record for write purposes when you do need to re-write it? At the same time if you are using record #1 for tracking and tracing work, you have a flag integer in it which notes this. No user can write the file without first checking with record number one and the flag which, if the file has been written after a user has modified the record, has changed from that next user's track data. OK, if they want to then also modify that record, and, then on new read before write, it is different than what was to be overwritten, you can make a decision if it is safe to overwrite that data, or alert the next user to re-examine and consider what to do. If the record that the new user wants to write isn't different as to original source, makes no difference if it is updated to at least that user of that different record.

                        In the case of many types of files this seems to work very well for those with discreet records for a given chunk use like master client information.
                        Mike Luther
                        [email protected]

                        Comment


                          #13
                          Mike, that's exactly what's in the article:

                          I. Thou Shalt Only Lock Records When Absolutely Necessary.
                          II. Thou Shalt Only Update Those Fields Changed By The Current User.

                          Read and retain image
                          Accept new values on screen until "Save"
                          Determine which fields the user changed based on the image he initially read
                          Read with lock
                          Update subject fields
                          Rewrite
                          Unlock

                          MCM
                          Michael Mattias
                          Tal Systems (retired)
                          Port Washington WI USA
                          [email protected]
                          http://www.talsystems.com

                          Comment


                            #14
                            Mike L.,

                            You could also check (having saved it earlier in a variable) the data file’s time-stamp. If it hasn’t changed, all the records are unchanged. If the time-stamp has changed, then check the particular records.

                            This would be faster on average unless other users update the data file frequently.
                            Algorithms - interesting mathematical techniques with program code included.

                            Comment


                              #15
                              How about no locks?
                              Open files only by the server and process client requests.
                              This is a link to a combined echo server and client that could be the start.

                              Comment


                                #16
                                How about no locks?
                                Open files only by the server and process client requests.
                                Well, sure, that would work.

                                But now you have to worry about creating a server and arranging for clients to call that server instead of doing their own file I-O.

                                Not a bad plan, but just off the top of my head I think it would be more economic to just handle the locking. (Or contract it out to someone).

                                MCM
                                Michael Mattias
                                Tal Systems (retired)
                                Port Washington WI USA
                                [email protected]
                                http://www.talsystems.com

                                Comment


                                  #17
                                  True Mark Hunter but ..

                                  Yes Mark

                                  > Mike L.,

                                  >You could also check (having saved it earlier in a >variable) the data file’s time-stamp. If it hasn’t changed, >all the records are unchanged. If the time-stamp has >changed, then check the particular records.

                                  >This would be faster on average unless other users update >the data file frequently.

                                  The above is precisely why the original thought was given here and Mike M confirms. In my case 20-30 people may have the file open for work at the same time. They all may be working, mostly on different record numbers. But not in some cases. Not only is the update time for the whole file not applicable here, but in cases, also the Entire Btrieve file system with all it's spiderweb there too is relevant in some cases for me.

                                  My professional management template written in PB's wonderful toolset is about as close to real-time for the entire professional facility as you can get. You can pull a complete income statement, balance sheet, complete inventory status, complete case records, complete phone line interaction .. everything .. after each and every time a client leaves a desk, walks in or out of the door, phones the place, or anyone in the place phones outside to all the numbers, tone sequence telco tracing; everything.

                                  It has even had all the global position coordinates in the database since the late 1970's - capable of vectoring and distance tracking every user vs. client move in real-time. Which might be interesting to some, but very much not wanted by lots of folks. Especially the professionals who would love to have this on the clients but do *NOT* want it for them as well, wink.

                                  As you can see, the question has been top focus for me and solved for my case in my own way since even 1974 and what was pre-PB .. VB from M/S and even direct into IBM's OS/2 before Gates even got to the table and the sign on Gordon Letwin's door, "Please do not poke, feed or tease the animal," was hung there. Grin! This all has been front and center for me since Heathkit H89 serial 960, chuckle, which I still have.
                                  Mike Luther
                                  [email protected]

                                  Comment


                                    #18
                                    Mike L, have to ask...

                                    Is that app that same PB/DOS application you've been writing about it seems forever?

                                    Yes? It is? Sheesh, that app has more than outlived any reasonable 'service life expectation.'

                                    MCM
                                    Michael Mattias
                                    Tal Systems (retired)
                                    Port Washington WI USA
                                    [email protected]
                                    http://www.talsystems.com

                                    Comment


                                      #19
                                      Yes, Mike, it is.

                                      People seem to have no real understanding that *ALL* 'professional' relationships between the 'professional' and the 'client' are the same, if you look at this in the 'scientific method'; forever in time. The only thing that changes are the definitions of the data and the rules that are thought by whomever to encapsulate the 'needed' perspective of the process. There is really no difference at all in medicine, law, government, police activity, sewer maintenance, hog hunting, nuclear warfare, world domination; whatever. It is all the same thing as to the relationship described above.

                                      It has not changes in thousands of years of human existence and never will into the future.

                                      Once you really do understand this and code a generic professional management template that can be simply overlaid by the different 'definitions' of the process, the actual operations process is timeless and the code you have created for the master process is never going to become obsolete.

                                      Makes no difference if you are a 'party' (human - animal - political' that one way or another is presented to another 'party' (thought to be human - animal - political) the process of the entire relationship is point specific:

                                      1.) A 'problem' exists between the interfaces.
                                      2.) Research must be done to define it.
                                      3.) A diagnosis must be defined as to it.
                                      4.) An action (treatment?) is set forth for it.
                                      5.) Post-treatment actions as needed are defined.
                                      6.) Continued action into the future as needed is used.

                                      Once you realize that it makes no difference if you are dealing with a cancer patient, a pole dancer, or a car with an active cell phone driver that just ran over a kid in a school zone. 'You' as a software OEM are dealing with interfacing the issue with the 'needed' professional interface to this and 'you' must also realize that the only way to really optimize the whole process is to be able to do everything needed in real-time, or at least near-real-time to 'manage' the process.

                                      The only way to be able to keep the horse from running away on you is to be able to yank the bit before it escapes from the site!

                                      You also come to understand that the entire process really cannot be carved up into little chunky bits with only local variables of data. It takes global variables and a really capable software tool set to participate in this.

                                      Which .. interestingly .. absolutely *MUST* remain the same as to the overall use from the master overview, on into the future as technology becomes more complex, but also *MUST* be able to still work with the system that is the basis and even may be hundreds of years old from the point where you now are in the creative process the envisions all this.

                                      The most critical part of all this as an OEM source for software for this kind of work is that as the individual or team involved, you don't lose sight of the past on the way toward the future!

                                      Interestingly, medicine has really contributed to all this even as to the cop in the patrol car pointing the gun, radar or otherwise at whatever! The standardization of the HIPAA data set, which can be completely contained in a struct and sub-struct set of code, actually contains the entire data set for a lot more than medical purposes if you understand how this all relates! It was a real blessing if one is willing to look at the whole process I describe above.

                                      Just modify the descriptions of things in the structs as needed for how to decide what to do with the conflict!

                                      But you also have to realize that the actual FDA rules for medical software that did originally come forth from the cancer treatment experiment at the Texas A&M Cyclotron in the 1970's absolutely *MUST* be a part of this if things are in real-time or near-real-time .. and .. touch the human body for either treatment or to take data and automatically punch it into formal records. No such computer program of hardware can at all be modified in any way by pushing new system stuff automatically into the field operations without a complete analysis of every bit of the hardware, every byte of the code even down to the CPU internal code! What we now know of today in the medical venue as a licensed medical device.

                                      In the mid-1970's I watched black window limo after limo come down University Drive in College Station to the Cyclotron. At the time I knew nothing about what was happening. Turns out it was the first research project for treating cancer patients with the highly focused cyclotron beam to kill cancer tumors! What I only six or so years later found out stunned me as I spent an hour on the phone with the chairman of what was next the software committee for the USA FDA.

                                      The research group that was doing the project, as told me, chose to change their computer system to a then newly released CPU that did not have a numeric co-processor on the motherboard. It had an error in the CPU that messed up the high definition math calculation results. The error over that trivial few dollar decision resulted in a significant over calculation of the beam intensity to be used for each person in treatment! And as told me, some 75 people were killed in the experiment before they figured out what had gone wrong.

                                      From which came the entire licensed medical device program in the USA and decision that *NO* operating system can be used in projected critical medical environments which can automatically push data or changes into the site. Any such changes *MUST* be made, even on the addition of any medical data into the actual records, by a qualified medical professional or system professional in real time as the changes are made!

                                      Of course you do now what Netbios over TCP/IP protocol is and that this is totally forbidden for any system like this, is of course, I'm sure. As well as contact with BOTS that can embed whatever ,,, and on and on and on.
                                      Wince...

                                      But the basic process of the professional management template is still EXACTLY the same as to the generic overview of what we talk about.

                                      And the whole overview is timeless, Mike.

                                      As the man told me that day in the 1970's Mike, when he heard about what I said above, there are certain things I can do and not do with what I created, as to the tools, operating systems, and hardware involved. I've followed the instructions precisely and will continue to do so. The master project definition will never change.
                                      Mike Luther
                                      [email protected]

                                      Comment


                                        #20
                                        All I wanted to know was, "Is it PB/DOS?"

                                        That question has, as they say, a binary solution set.
                                        Michael Mattias
                                        Tal Systems (retired)
                                        Port Washington WI USA
                                        [email protected]
                                        http://www.talsystems.com

                                        Comment

                                        Working...
                                        X
                                        😀
                                        🥰
                                        🤢
                                        😎
                                        😡
                                        👍
                                        👎