[MUD-Dev] C&C and Event Rescheduling

clawrenc at cup.hp.com clawrenc at cup.hp.com
Thu Jul 24 17:50:08 New Zealand Standard Time 1997


In <33D63D8C.167EB0E7 at iname.com>, on 07/23/97 
   at 09:53 PM, Shawn Halpenny <malachai at iname.com> said:

>clawrenc at cup.hp.com wrote:
>> In <33CFCE6E.41C67EA6 at iname.com>, on 07/18/97
>>    at 01:22 PM, Shawn Halpenny <malachai at iname.com> said:

>>   Re: #5.  How do you determine that the object has changed during the
>> execution of the event?  I do this by always keeping an original copy
>> of the object to compare to the copy current in the DB and then do a
>> bit-wise comparison of the two objects.  The original copy is the
>> second copy made above for a modification.
>>
>>   Aside: I'm actually getting *slightly* neater than this as the
>> current plan encludes only making a copy of the object
>> attribute/member which is changed, and then only comparing that at
>> C&C.

>Right now, my design is to just do a bitwise comparison just like
>above, but I'm also thinking of something involving an object
>checksum of sorts computed when an object is committed.  

A simple approach (oustide of disk space) is to expand your object
definition to also enclude a time stamp of the last change.  This can
be a nanosecond clock or a time_t.  If different the objects fail C&C. 
If the same, *then* do the bit comparison when they're the same.  

This could be further simpliefied by adding a count variable to sit
along side the time.  Upon every object modification that's commited,
the time value is set to the time of the commit.  If that setting of
the time value actually doesn't change it (same value before and
after), increment the count value prior to commiting.  Now you
comparison devolves to merely checking that both the time stamp and
the count valuye are the same.  If they are you are guaranteed that
the objects are the same -- at some extra storage costs (5 bytes per
object).

Note: This approach has the benefit of avoiding the problem below
(which I don't consider a problem).

>Do your
>events keep track of the attributes they touch or is that handled
>entirely by the DB?  

This is currently in a mess.  Actually that's an understatement.  I'm
partially dug into Arjuna to use it as a persistant store.  Part and
parcel of this idea would be devolving MUD objects at the storage into
individual objects, one each per attribute and method.  Its then a
simple matter of flagging the references at runtime to resolve what
bits got checked/changed ans what didn't.

>Is there a problem with a situation where a
>single object with attributes touched by two events within the
>duration of a third event using the same object could cause some
>attributes touched by the third event to falsely pass the comparison?

Yes, but I don't consider this a problem:

  Players A, B and C are in room X.  

  There is a chest Q in room X.

  Player A closes the chest (event 1).

  Player B opens the chest (event 2).

  Player C puts something in the chest (event 3).

Event 3 starts execution first.

Event 3 checks that the chest is open.

Event 1 starts execution.

Event 1 commits, leaving the chest now closed.

Event 2 starts execution.

Event 2 commits, leaving the chest now open.

Event 3 compleats, finds that the state of the chest is unchanged
since it started execution, and commits successfully.

Logically interesting I'll admit, but not a problem that I can see.

>>   Re: #7.  Similarly I post messages (flags really) to all the members
>> of the interested parties lists for all the objects that a
>> successfully committed transaction modified.  The effect of those
>> flags is that the next time those events traverse a block boundary
>> (essentially any piece of code wrapped in {braces}, such as entering
>> or leaving an IF, or WHILE etc), the flag gets checked and if TRUE,
>> the event aborts to reschedule.

>I do much the same, using the exception mechanism of the internal
>language.

I explicitly didn't put this in the language exceptions as once an
event compleats and attempts C&C there' no language running to receive
the exception.  A new event would have to be started to catch the
exception...

>> Concern:
>> 
>>   An event generated IO.  How do you handle when it reschedules?
>> Think about things like SAY, TELL, LOOK, etc for example cases.

>As of yet, I don't.  In the last few weeks I've been doing the
>"formal" design of the base systems (network, DB, event handling). 

Handling IO is a pretty big part of any server design.

Consider:

  Player A types, "get axe".

  Event 1 runs the "get axe" code.

  Event 1 issues the IO, "You pick up the axe." back to the player.

  Player B picks up the axe.  This event sucessfully commits.

  Event 1 then tries to C&C, fails, reschedules, and pops back with
"What axe?"

  Meanwhile the player A sees:

    > get axe
    You pick up the axe.
    B picks up the axe.
    What axe?
    > i
    ...no axe...

>Handling commands where events that have to touch a number of objects
>that have likely changed by the time the event is processed isn't
>something I've worked on yet.  Therein lies the difficulty.

Its worth attention.

>>   Going back to the case of the two rooms A and B, and the 50 players
>> moving between them.
>> 
>>   If you can, split your room/motion model so that moving between
>> rooms requires two events:
>> 
>>   #1 Move out of current room.
>> 
>>   #2 After sucessfully doing #1, move into new room.
>> 
>> The question of course is "where" the player is having compleated #1,
>> and processing on #2.  

>Indeed.  What happens where an event occurs expecting Bubba to be in
>a room, yet he is technically in between?

The doorway?  It is a logical question.  You can either wrap your
system about it (eg have the door being a logical, if temporary,
location), or try something else.  Reducing possible contention is the
key.

>> Note: I dug into this TELL implemenation a while back on the list,
>> along with details on how to handle channels, SAY, WHISPER etc
>> efficiently in this sort of event driven C&C model.  If you want I'll
>> try and dig it up.

>If you could, thank you.  

Will try.  The wife is off out of state for a week, leaving me with
the munchkins, so time will be short.

>At the moment, I'm thinking along the lines
>of the "tell" verb posting an event for each receiving player, rather
>than a root object to handle it.

Largely there's no semantic difference.  The trick is to not have an
event which is dependant on successfully iterating the entire player
base (or any group object classification for that matter) within a
single event.  If you do that it will rarely successfully C&C and the
player objects change.  

Another side effect of the same problem:

  How do you handle broadcasting state changes to other objects?

>> Look at it this way:
>> 
>>   50 events are simultaneously executing on your server.  Under those
>> conditions a new event X (say Bubba moving from room A to room B) can
>> expect to compleat in T real world clock ticks.
>> 
>>   Due to rescheduling, priority levels, or just a paucity of events,
>> there are no __NO__ events executing on your server.  Under those
>> conditions a new event X (say Bubba moving from room A to room B) can
>> expect to compleat in U real world clock ticks where U<T.
>> 
>> Part of my attention here is that I don't want events which are
>> borderline on their time values managing to C&C only because they
>> throw the system into single-threaded mode and then squeak thru
>> because they have the whole damn CPU to themselves.
>> 
>> Note: A lot of this is obviated by hanging the way you measure an
>> event's execution time.  I originally crafted the above schema when I
>> was measuring event time in real world CPU clock ticks.  I have slated
>> to change this to some sort of measurement of internal processing
>> time, but have yet to come up with a decent system.

>Can this sort of thing be remedied with smaller time units?  If
>events can only begin execution on the edge of a tick, you'd likely
>have more contention within each tick than with smaller granularity.

My time units are RL seconds (ie a time_t).  I could go smaller but I
don't see a reason. 

--
J C Lawrence                           Internet: claw at null.net
(Contractor)                           Internet: coder at ibm.net
---------------(*)               Internet: clawrenc at cup.hp.com
...Honorary Member Clan McFUD -- Teamer's Avenging Monolith...




More information about the MUD-Dev mailing list