RejectedSoftware Forums

Sign up

Sending complex messages?

What is going on here?

Code:

class Message
{
...
}

task.send(new immutable(Message)(args));

source/vibe/concurrency.d(1148): Error: can only initialize const
member expandfield_0 inside constructor
source/vibe/concurrency.d(1065): Error: template instance
vibe.core.concurrency.variantWithIsolatedSupport!(immutable(Message))
error instantiating
source/client/connection.d(54): instantiated from here:
send!(immutable(Message))
source/client/connection.d(54): Error: template instance
vibe.core.concurrency.send!(immutable(Message)) error instantiating

Re: Sending complex messages?

On Sat, 2 Nov 2013 18:07:40 -0400, Shammah Chancellor wrote:

What is going on here?

Code:

class Message
{
...
}

task.send(new immutable(Message)(args));

source/vibe/concurrency.d(1148): Error: can only initialize const
member expandfield_0 inside constructor
source/vibe/concurrency.d(1065): Error: template instance
vibe.core.concurrency.variantWithIsolatedSupport!(immutable(Message))
error instantiating
source/client/connection.d(54): instantiated from here:
send!(immutable(Message))
source/client/connection.d(54): Error: template instance
vibe.core.concurrency.send!(immutable(Message)) error instantiating

This was a problem with how values were packed in a std.typecons.Tuple for sending. The latest GIT master works around this and should function properly now (8ab6bcc).

Re: Sending complex messages?

On 2013-11-03 13:05:16 +0000, Sönke Ludwig said:

On Sat, 2 Nov 2013 18:07:40 -0400, Shammah Chancellor wrote:

What is going on here?

Code:

class Message

{

...

}

task.send(new immutable(Message)(args));

source/vibe/concurrency.d(1148): Error: can only initialize const

member expandfield_0 inside constructor

source/vibe/concurrency.d(1065): Error: template instance

vibe.core.concurrency.variantWithIsolatedSupport!(immutable(Message))

error instantiating

source/client/connection.d(54): instantiated from here:

send!(immutable(Message))

source/client/connection.d(54): Error: template instance

vibe.core.concurrency.send!(immutable(Message)) error instantiating

This was a problem with how values were packed in a
std.typecons.Tuple for sending. The latest GIT master works around
this and should function properly now
(8ab6bcc).

Sönke,

Alright. I've tried using shared classes, Isolated classes, and
immutable classes. None of them work for a variety of reasons:

shared classes <-- Don't work because of external dependencies.
Making every member variable shared, breaks too much stuff.
Isolated classes <-- I need to be able to send the same reference to
multiple threads, so .move() is out of the question.
Immutable classes <-- Can't even get them to instantiate since the
constructors have to be strongly pure. Also, I can't deserialize into
an immutable class!

How am I supposed to send complex class messages?

R/
Shammah

Re: Sending complex messages?

On Sat, 9 Nov 2013 14:45:30 -0500, Shammah Chancellor wrote:

Sönke,

Alright. I've tried using shared classes, Isolated classes, and
immutable classes. None of them work for a variety of reasons:

shared classes <-- Don't work because of external dependencies.
Making every member variable shared, breaks too much stuff.
Isolated classes <-- I need to be able to send the same reference to
multiple threads, so .move() is out of the question.
Immutable classes <-- Can't even get them to instantiate since the
constructors have to be strongly pure. Also, I can't deserialize into
an immutable class!

How am I supposed to send complex class messages?

R/
Shammah

You should try the lock() function in vibe.core.concurrency! It uses a scheme if shared usage that Walter Bright once proposed in a discussion and it makes shared with classes actually bearable.

Basically you just define a normal class without any shared annotations, but create the instance using auto c = cast(shared)new C. You will then not be able to use any methods of that class, but calling c.lock() will give you back scoped access while the instance's monitor is locked. Beware though that only access to pure methods is allowed to guarantee safety (no unshared references must escape), but this is currently not enforced due to compiler issues I had some time ago (not sure how DMD 2.064 behaves now).

Re: Sending complex messages?

On 2013-11-10 08:21:09 +0000, Sönke Ludwig said:

On Sat, 9 Nov 2013 14:45:30 -0500, Shammah Chancellor wrote:

Sönke,

Alright. I've tried using shared classes, Isolated classes, and

immutable classes. None of them work for a variety of reasons:

shared classes <-- Don't work because of external dependencies.

Making every member variable shared, breaks too much stuff.

Isolated classes <-- I need to be able to send the same reference to

multiple threads, so .move() is out of the question.

Immutable classes <-- Can't even get them to instantiate since the

constructors have to be strongly pure. Also, I can't deserialize into

an immutable class!

How am I supposed to send complex class messages?

R/

Shammah

You should try the lock() function in vibe.core.concurrency! It
uses a scheme if shared usage that Walter Bright once proposed in a
discussion and it makes shared with classes actually bearable.

Basically you just define a normal class without any shared
annotations, but create the instance using auto c = cast(shared)new <br>C. You will then not be able to use any methods of that class, but
calling c.lock() will give you back scoped access while the
instance's monitor is locked. Beware though that only access to pure
methods is allowed to guarantee safety (no unshared references must
escape), but this is currently not enforced due to compiler issues I
had some time ago (not sure how DMD 2.064 behaves now).

Ahh.. Handy. There is so much good stuff hiding out in vibe-d. Is
there any consideration for trying to get this sort of stuff commited
back phobos?

R/
Shammah

Re: Sending complex messages?

Am 10.11.2013 22:17, schrieb Shammah Chancellor:

On 2013-11-10 08:21:09 +0000, Sönke Ludwig said:

On Sat, 9 Nov 2013 14:45:30 -0500, Shammah Chancellor wrote:

Sönke,

Alright. I've tried using shared classes, Isolated classes, and
immutable classes. None of them work for a variety of reasons:

shared classes <-- Don't work because of external dependencies.
Making every member variable shared, breaks too much stuff.

Isolated classes <-- I need to be able to send the same reference to
multiple threads, so .move() is out of the question.

Immutable classes <-- Can't even get them to instantiate since the
constructors have to be strongly pure. Also, I can't deserialize into
an immutable class!

How am I supposed to send complex class messages?

R/

Shammah

You should try the lock() function in vibe.core.concurrency! It
uses a scheme if shared usage that Walter Bright once proposed in a
discussion and it makes shared with classes actually bearable.

Basically you just define a normal class without any shared
annotations, but create the instance using auto c = cast(shared)new<br>C. You will then not be able to use any methods of that class, but
calling c.lock() will give you back scoped access while the
instance's monitor is locked. Beware though that only access to pure
methods is allowed to guarantee safety (no unshared references must
escape), but this is currently not enforced due to compiler issues I
had some time ago (not sure how DMD 2.064 behaves now).

Ahh.. Handy. There is so much good stuff hiding out in vibe-d. Is
there any consideration for trying to get this sort of stuff commited
back phobos?

R/
Shammah

Yes, a lot of stuff (e.g. everything in vibe.util and
vibe.core.concurrency) would be great to have in Phobos. However,
actually getting code in Phobos is a very involved process and I don't
have the time to do so. But many things are also good prototypes against
which actual new Phobos features can be measured (e.g. the new
std.allocator framework) and which will then be replaced by the Phobos
versions eventually.

Re: Sending complex messages?

On 2013-11-10 08:21:09 +0000, Sönke Ludwig said:

On Sat, 9 Nov 2013 14:45:30 -0500, Shammah Chancellor wrote:

Sönke,

Alright. I've tried using shared classes, Isolated classes, and

immutable classes. None of them work for a variety of reasons:

shared classes <-- Don't work because of external dependencies.

Making every member variable shared, breaks too much stuff.

Isolated classes <-- I need to be able to send the same reference to

multiple threads, so .move() is out of the question.

Immutable classes <-- Can't even get them to instantiate since the

constructors have to be strongly pure. Also, I can't deserialize into

an immutable class!

How am I supposed to send complex class messages?

R/

Shammah

You should try the lock() function in vibe.core.concurrency! It
uses a scheme if shared usage that Walter Bright once proposed in a
discussion and it makes shared with classes actually bearable.

Basically you just define a normal class without any shared
annotations, but create the instance using auto c = cast(shared)new <br>C. You will then not be able to use any methods of that class, but
calling c.lock() will give you back scoped access while the
instance's monitor is locked. Beware though that only access to pure
methods is allowed to guarantee safety (no unshared references must
escape), but this is currently not enforced due to compiler issues I
had some time ago (not sure how DMD 2.064 behaves now).

I tried using immutable messages again after some more reworking, and I
find that either std.concurrency or Vibe-D is trying to create the
parameters to the receiver() functions based on their type.

Code:

send( new immutable Foo() );
receive( (immutable Foo x) { ... } );

^-- can't work right now because internally it creates a list of
parameters as an IsolatedTypeTuple!(immutable Foo)

This fails inside of std.variant because IsolatedTypeTuple!(immutable
Foo) cannot be assigned to. It needs to wrap immutable reference
types with Rebindable!() somehow.

I don't want to use lock() since i'm only reading properties from the
class everywhere. That would cause the threads to block each other
while reading. I have fallen back to just casting to remove shared.
Seems like not a good solution though.

Re: Sending complex messages?

On 2013-11-11 17:42:50 +0000, Shammah Chancellor said:

On 2013-11-10 08:21:09 +0000, Sönke Ludwig said:

On Sat, 9 Nov 2013 14:45:30 -0500, Shammah Chancellor wrote:

Sönke,

Alright. I've tried using shared classes, Isolated classes, and

immutable classes. None of them work for a variety of reasons:

shared classes <-- Don't work because of external dependencies.

Making every member variable shared, breaks too much stuff.

Isolated classes <-- I need to be able to send the same reference to

multiple threads, so .move() is out of the question.

Immutable classes <-- Can't even get them to instantiate since the

constructors have to be strongly pure. Also, I can't deserialize into

an immutable class!

How am I supposed to send complex class messages?

R/

Shammah

You should try the lock() function in vibe.core.concurrency! It
uses a scheme if shared usage that Walter Bright once proposed in a
discussion and it makes shared with classes actually bearable.

Basically you just define a normal class without any shared
annotations, but create the instance using auto c = cast(shared)new <br>C. You will then not be able to use any methods of that class, but
calling c.lock() will give you back scoped access while the
instance's monitor is locked. Beware though that only access to pure
methods is allowed to guarantee safety (no unshared references must
escape), but this is currently not enforced due to compiler issues I
had some time ago (not sure how DMD 2.064 behaves now).

I tried using immutable messages again after some more reworking, and I
find that either std.concurrency or Vibe-D is trying to create the
parameters to the receiver() functions based on their type.

Code:

send( new immutable Foo() );
receive( (immutable Foo x) { ... } );

^-- can't work right now because internally it creates a list of
parameters as an IsolatedTypeTuple!(immutable Foo)

This fails inside of std.variant because IsolatedTypeTuple!(immutable
Foo) cannot be assigned to. It needs to wrap immutable reference
types with Rebindable!() somehow.

I don't want to use lock() since i'm only reading properties from the
class everywhere. That would cause the threads to block each other
while reading. I have fallen back to just casting to remove shared.
Seems like not a good solution though.

Here is a testcase:

import std.stdio;
import vibe.d;

class Foo
{
string msg;
this(immutable string msg) pure immutable
{

this.msg = msg;

}
}

static this()
{
auto foo = new immutable Foo(cast(immutable)"msg");
auto x = runTask( ()
{

receive((immutable Foo x)
    {
      writeln( x.msg);
    });

});

x.send(foo);
x.join();
}