RejectedSoftware Forums

Sign up

Pages: 1 2

StdFileStream question

I wonder why this class creates two extra threads? I thought such things can/should be implemented using the event loop, which provides non-blocking read/write functionality?

Re: StdFileStream question

Am 07.11.2017 um 15:00 schrieb Dietmar Maurer:

I wonder why this class creates two extra threads? I thought such things can/should be implemented using the event loop, which provides non-blocking read/write functionality?

True, StdFileStream just hasn't been a priority so far. There have
been recurrent questions about a solution in general, so I just
integrated the generic version that I did for a non-performance-critical
piece of software a while ago. Integrating it into the event loop
requires a bit more work, because Windows behaves very differently and
it has implications for other code that directly uses the same I/O
handles. But it is something that should definitely be tackled at some
point.

To accelerate the process, it would of course also be possible to work
on this step by step, keeping the thread based approach for Windows and
using non-blocking I/O for Posix systems.

Re: StdFileStream question

To accelerate the process, it would of course also be possible to work
on this step by step, keeping the thread based approach for Windows and
using non-blocking I/O for Posix systems.

Also, I do not really understand how FileStream implementation works.
Seems current drivers use module vibe.core.drivers.threadedfile,
but that file contains the following comment:

Thread based asynchronous file I/O fallback implementation

But the module does not use any threads, and use blocking IO calls.
So all vibe.d file-io is in fact blocking? What do I miss?

Re: StdFileStream question

On Wed, 08 Nov 2017 12:08:15 GMT, Dietmar Maurer wrote:

To accelerate the process, it would of course also be possible to work
on this step by step, keeping the thread based approach for Windows and
using non-blocking I/O for Posix systems.

Also, I do not really understand how FileStream implementation works.
Seems current drivers use module vibe.core.drivers.threadedfile,
but that file contains the following comment:

Thread based asynchronous file I/O fallback implementation

But the module does not use any threads, and use blocking IO calls.
So all vibe.d file-io is in fact blocking? What do I miss?

The old Posix implementation indeed just used blocking calls (except for the win32 driver). However, it will be deprecated very soon, and the replacement, vibe-core, already uses actual thread-backed I/O for non-Windows systems through the "eventcore" library: https://github.com/vibe-d/eventcore/blob/master/source/eventcore/drivers/threadedfile.d

Even if the old implementation is currently still the default, I'd recommend starting any new developments with the new module, not just for this reason, but also because to uses much more principled, robust, and idiomatic approaches in many areas. The switch can be made by inserting this into the project's dub.sdl:

dependency "vibe-d:core" version="~>0.8.1"
subConfiguration "vibe-d:core" "vibe-core"

or for dub.json:

{
    ...
    "dependencies": {
        ...
        "vibe-d:core": "~>0.8.1"
    },
    "subConfigurations": {
        "vibe-d:core": "vibe-core"
    }
}

The only gotcha is that even if in theory vibe-core is considerably faster than the old implementation, due to the excessive use of class based polymorphism in the HTTP module, the HTTP server will actually perform worse than before. This problem will be addressed in the near future.

Re: StdFileStream question

But the module does not use any threads, and use blocking IO calls.
So all vibe.d file-io is in fact blocking? What do I miss?

The old Posix implementation indeed just used blocking calls (except for the win32 driver). However, it will be deprecated very soon, and the replacement, vibe-core, already uses actual thread-backed I/O for non-Windows systems through the "eventcore" library: https://github.com/vibe-d/eventcore/blob/master/source/eventcore/drivers/threadedfile.d

I do not really get why you use threads. Why don't you simply use libevent2 for that (that is the whole purpose of having libevent2)?

Re: StdFileStream question

Am 08.11.2017 um 17:32 schrieb Dietmar Maurer:

But the module does not use any threads, and use blocking IO calls.
So all vibe.d file-io is in fact blocking? What do I miss?

The old Posix implementation indeed just used blocking calls (except for the win32 driver). However, it will be deprecated very soon, and the replacement, vibe-core, already uses actual thread-backed I/O for non-Windows systems through the "eventcore" library: https://github.com/vibe-d/eventcore/blob/master/source/eventcore/drivers/threadedfile.d

I do not really get why you use threads. Why don't you simply use libevent2 for that (that is the whole purpose of having libevent2)?

Eventcore doesn't use libevent*, but directly talks to the operating
system APIs. But as far as I know, libevent also uses a thread pool for
file I/O. Until recently, there has been no way to implement
asynchronous file operations without threads on Linux. There is the aio
API in glibc, but even that uses threads internally.

However, there is libaio, which wraps the actual kernel mode
asynchronous I/O support available on all modern Linux kernels, and this
is what will likely be targeted in the future. Until then, and for other
operating systems for which no explicit asynchronous file I/O support
has been implemented, the generic multi-threaded approach provides a
pretty decent fallback.

  • The reason being to get more control over performance characteristics
    of the abstraction layer, and to avoid the external library dependency,
    which is a frequent issue for new users or different operating systems
    with differing libevent versions or none at all.

Unfortunately libaio-dev also needs to be explicitly installed, so based
on the latter argument it may be added as an opt-in feature, keeping
thread based file I/O as the default.

Re: StdFileStream question

On Wed, 8 Nov 2017 18:14:14 +0100, Sönke Ludwig wrote:

But as far as I know, libevent also uses a thread pool for
file I/O.

Correction: libevent does not support file I/O at all. I was thinking about libuv here.

Re: StdFileStream question

On Wed, 08 Nov 2017 17:22:46 GMT, Sönke Ludwig wrote:

On Wed, 8 Nov 2017 18:14:14 +0100, Sönke Ludwig wrote:

But as far as I know, libevent also uses a thread pool for
file I/O.

Correction: libevent does not support file I/O at all. I was thinking about libuv here.

With libevent, you open the file with O_NOBLOCK, and then use poll/select to wait until it gets a readable/writable event. Then you can do the non blocking read-write. It is quite easy to use/implement that using your current libevent2 D bindings.

int fd = open(..., O_NOBLOCK ...)
FileDescriptorEvent ev = createFileDescriptorEvent(out_fd,
					FileDescriptorEvent.Trigger.read,
					FileDescriptorEvent.Mode.persistent);
ev.wait();
read(...)

This is not 100% reliable (may block in some cases), but works quite well in practice.

What benchmark do you use to test the new threadedfile implementation? I would like to compare with a correct libevent based implementation.

Re: StdFileStream question

Am 08.11.2017 um 19:33 schrieb Dietmar Maurer:

On Wed, 08 Nov 2017 17:22:46 GMT, Sönke Ludwig wrote:

On Wed, 8 Nov 2017 18:14:14 +0100, Sönke Ludwig wrote:

But as far as I know, libevent also uses a thread pool for
file I/O.

Correction: libevent does not support file I/O at all. I was thinking about libuv here.

With libevent, you open the file with O_NOBLOCK, and then use poll/select to wait until it gets a readable/writable event. Then you can do the non blocking read-write. It is quite easy to use/implement that using your current libevent2 D bindings.

 int fd = open(..., O_NOBLOCK ...)
 FileDescriptorEvent ev = createFileDescriptorEvent(out_fd,
					FileDescriptorEvent.Trigger.read,
					FileDescriptorEvent.Mode.persistent);
 ev.wait();
 read(...)

This is not 100% reliable (may block in some cases), but works quite well in practice.

What benchmark do you use to test the new threadedfile implementation? I would like to compare with a correct libevent based implementation.

Files don't support non-blocking operation, they will always be flagged
as ready for read/write. This will work, but always blocks. There are
some "files" that are actually sockets or pipes for which this will in
fact work, but not for regular files.

Re: StdFileStream question

Files don't support non-blocking operation, they will always be flagged
as ready for read/write. This will work, but always blocks. There are
some "files" that are actually sockets or pipes for which this will in
fact work, but not for regular files.

Ah, I see. But it will work perfectly for pipes and sockets.

I saw your PipedProcess implementation https://gist.github.com/s-ludwig/8434299 and noticed that this spawns up to 4 threads, where only one would be required?

Or is thread creation really that cheap and it is not worth to special case such things?

Pages: 1 2