RejectedSoftware Forums

Sign up

using TCPConnection.write in several tasks

Hi!

I was wondering if it's legal to use TCPConnection.write in several tasks, like:

TCPConnection myConnection;
runTask({
  myConnection.write(lotsOfData0);
});
myConnection.write(lotsOfData1);

will this mean that first lotsOfData0 or lotsOfData1 will get send and then the other one, or will it result in, some bytes of lotsOfData0, then some bytes lotsOfData1 will get send, and so on?

I couldn't find any documentation or search results on that topic, would you mind pointing me to the right direction,
thx Markus

Re: using TCPConnection.write in several tasks

On Mon, 09 Oct 2017 12:18:38 GMT, Markus wrote:

Hi!

I was wondering if it's legal to use TCPConnection.write in several tasks, like:

TCPConnection myConnection;
runTask({
  myConnection.write(lotsOfData0);
});
myConnection.write(lotsOfData1);

will this mean that first lotsOfData0 or lotsOfData1 will get send and then the other one, or will it result in, some bytes of lotsOfData0, then some bytes lotsOfData1 will get send, and so on?

I couldn't find any documentation or search results on that topic, would you mind pointing me to the right direction,
thx Markus

I could be wrong but I think this will mean you're sending both sets of data at the same time. RunTask just runs the task asyncronously, and should allow both "write" operations to happen at the same time... which seems like a bad idea :-)

Re: using TCPConnection.write in several tasks

Am 09.10.2017 um 14:18 schrieb Markus:

Hi!

I was wondering if it's legal to use TCPConnection.write in several tasks, like:

TCPConnection myConnection;
runTask({
   myConnection.write(lotsOfData0);
});
myConnection.write(lotsOfData1);

will this mean that first lotsOfData0 or lotsOfData1 will get send and then the other one, or will it result in, some bytes of lotsOfData0, then some bytes lotsOfData1 will get send, and so on?

I couldn't find any documentation or search results on that topic, would you mind pointing me to the right direction,
thx Markus

Currently, concurrent writes are forbidden and will usually lead to an
assertion failure. A TaskMutex needs to be used to ensure exclusive
access. The same applies also to concurrent reads.

However, in later versions of eventcore (which will be the default event
loop abstraction), it is planned to enqueue reads and writes in the
order in which they get initiated, so the code above would become legal.
Under the normal semantics, lotsOfData0 would then be sent first, as
runTask will eagerly start to execute the task before returning after
the first yield/blocking operation occurred.

Re: using TCPConnection.write in several tasks

On Mon, 9 Oct 2017 23:03:42 +0200, Sönke Ludwig wrote:

Currently, concurrent writes are forbidden and will usually lead to an
assertion failure. A TaskMutex needs to be used to ensure exclusive
access. The same applies also to concurrent reads.

Got it! however I really like lock-free development.
Do you think something like

Queue writeQueue;
runTask({
  // I'm the writing task
  while (writeQueue.pop(...)) {
    // do the writing
  }
});

asyncTask({
  writeQueue.push({
    // do the send
  });
});

writeQueue.push({
  // do another send
});

would be nicer?
if so, could you point me in the right direction.
I only found "core.task.MessageQueue", but I'm not sure it'd be the right choice. Or maybe rather like in the chat tutorial by using ManualEvent on combination with a simple ubyte[] list?

On Mon, 9 Oct 2017 23:03:42 +0200, Sönke Ludwig wrote:

However, in later versions of eventcore (which will be the default event
loop abstraction), it is planned to enqueue reads and writes in the
order in which they get initiated, so the code above would become legal.
Under the normal semantics, lotsOfData0 would then be sent first, as
runTask will eagerly start to execute the task before returning after
the first yield/blocking operation occurred.

lovely!

Re: using TCPConnection.write in several tasks

On Mon, 09 Oct 2017 16:30:57 GMT, Andrew Chapman wrote:

I could be wrong but I think this will mean you're sending both sets of data at the same time. RunTask just runs the task asyncronously, and should allow both "write" operations to happen at the same time... which seems like a bad idea :-)

:-) thx

Re: using TCPConnection.write in several tasks

On Tue, 10 Oct 2017 12:07:08 GMT, Markus wrote:

On Mon, 9 Oct 2017 23:03:42 +0200, Sönke Ludwig wrote:

Currently, concurrent writes are forbidden and will usually lead to an
assertion failure. A TaskMutex needs to be used to ensure exclusive
access. The same applies also to concurrent reads.
Got it! however I really like lock-free development.
Do you think something like

Queue writeQueue;
runTask({
  // I'm the writing task
  while (writeQueue.pop(...)) {
    // do the writing
  }
});

asyncTask({
  writeQueue.push({
    // do the send
  });
});

writeQueue.push({
  // do another send
});

would be nicer?
if so, could you point me in the right direction.
I only found "core.task.MessageQueue", but I'm not sure it'd be the right choice. Or maybe rather like in the chat tutorial by using ManualEvent on combination with a simple ubyte[] list?

The ready-to-use solution to this would be using the message passing API of std.concurrency, which integrates with vibe.d's task/fiber model. There is also an initial sketch of a Go-like channel implementation for vibe-core, which would be faster and strongly typed. It's not finished yet, but you could simply use a copy of it: https://github.com/vibe-d/vibe-core/pull/25