Jump to content
  • Advertisement
Sign in to follow this  
webwraith

Accessing data in a message-based environment

This topic is 3156 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm writing a scripting language that deals with each object instance as a seperate process, but have come across a slight snag in the design. Currently, communication is event-based, with each instance having its own event queue, and the VM passing or dropping events, depending on whether or not the instance deals with it. What would be a good way to allow one instance to access another instances data (a public variable, basically) in an effectively thread-safe manner without the script writer having to be aware of it?

Share this post


Link to post
Share on other sites
Advertisement
There are some pure message based languages and the way they deal with it is to create deep copies of the object they send with the messages and have some arbitration scheme for merging or updating the instance data. I think Erlang does something like this.

I think a more workable approach would be the concept of a virtual data channel managed by a centralized data service. So each object can run in its own process/VM/remotely and when it has data it wants to share it binds that blob of data to a data service and is given a key (which globally uniquely identifies that data). It then passes this key to anyone interested in modifying or peeking at it.

Then process 2 can query and modify the data element through an intermediary service which can insure a thread safe and transaction safe protocol, similar to how database works, but this service is optimized for realtime performance not for data persistence.

Good Luck!

-ddn

Share this post


Link to post
Share on other sites
So a form of accessor, then? Would the instance that is exposing the data need to use the same method to access it? If not that would still prove problematic if the owner of the data is changing it during its own process/thread, and another is using it in theirs

[Edited by - webwraith on October 25, 2009 7:05:32 PM]

Share this post


Link to post
Share on other sites
The database model handles all that, concurrent writes, locking, rollback, persistence and ownership. As long as you have a central authority on the data u can say who has the right of ownership and what the "most" current value is, instead of leaving that up to each object.

Here is an example of such a system..

http://en.wikipedia.org/wiki/Berkeley_DB

Enjoy!

-ddn

Share this post


Link to post
Share on other sites
Quote:
Original post by webwraith
What would be a good way to allow one instance to access another instances data (a public variable, basically) in an effectively thread-safe manner without the script writer having to be aware of it?
I have an "actor system" at home that works much the same way (each object can be running on it's own thread, but doesn't have to be), and messages are used for communication.

To solve the data-sharing problem, I didn't want to make the messages huge (e.g. copy entire objects into the message) and didn't want to use mutexes to share state.
Instead, I allow objects to mark some of their variables as "shared". Once per frame, while no objects are executing, every shared variable is copied into a read-only buffer.
This allows any object to read values out of other objects "shared buffers" -- accessor functions return the buffered variable, while internal calculations are done on the real variable.

A C++ implementation of one of these types of objects might look like:
class Widget
{
public:
//This is thread safe:
int GetValue() const
{
ASSERT( scheduler.IsUpdatingObjects() )
return buffer.value;
}

//This is thread safe, it creates a message to call the non-thread safe function later in time:
void IncrementValue()
{
ASSERT( scheduler.IsUpdatingObjects() )
scheduler.PushMessage( this, &IncrementValue_ );
}

//internal use by scheduler ONLY:
void UpdateShared()
{
ASSERT( !scheduler.IsUpdatingObjects() )
buffer.value = m_Value;
}
private:
//NOT thread safe, call via a message:
void IncrementValue_()
{
ASSERT( scheduler.IsUpdatingObjects() )
++m_Value;
}

int m_Value;
struct {
int value;
} buffer;
};
Obviously I don't actually write C++ classes like this, I just have a mechanism for saying "the member variable m_Value is shared, please buffer it for me" and "the member function IncrementValue is a message, please buffer any calls to it for me", and beyond that, the class authors don't need to know anything about thread safety.

Share this post


Link to post
Share on other sites

The classic 'object-oriented' approach would be get/set functions called against the object which you would convert to events with replies (get value or set value confirmation). The object would have a chance to vet the operations on its end if desired. Permission to access mechanisms could be added ontop.

Possibly you could expand that system to include register/unregister a subscription to the objects element (for read access) which would post signal events to a subscriber whenever the subscribed to data was modified. That subscription could be expanded to cover a group of data elements (not just limited to one) to handle frequent cases of associated/interrelated data.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!