vibe.d beta banner
get vibe.d
0.8.0

Asynchronous I/O that doesn’t get in your way, written in D

Introducing vibe.d's new core module

Introducing vibe.d's new core module

Header image
Mon, 10 Jul 2017vibe.d's core package contains the fundamental building blocks for all of the high-level functionality, such as the HTTP server, the web framework, database connectivity and so on. It's responsible for running the event loop and for layering the fiber based task concept on top, hiding the event based nature of the system. The original system has been almost rewritten from scratch, modernizing and optimizing the existing code base as rigorously as possible without breaking backwards compatibility for the library user.

The package in its original form has been around from the beginnings of vibe.d in 2012. A lot of things about the D language were different at that time. For example, user defined attributes and the memory safe subset didn't exist, automatic reference counting was impossible to implement robustly due to compiler issues, and the introspection capabilities of the language were still quite limited.

Some properties of the original design that emerged out of this nowadays seem outdated and pose a limit on how fast or how memory safe the system can be. Most of the objects were class based, allocated with the GC and the fundamental stream design was based on interfaces, which means virtual function calls were all over the place and function inlining was often not possible.

The event loop abstraction was originally based on top of libevent, with the fiber scheduling logic directly layered on top. Later, more drivers were added, based on libev, the win32 API and libasync. The big drawback of this direct layering became more and more visible, as defects appeared in this area over and over again. Each driver had to do the full logic of properly suspending and resuming tasks, handling exceptions, timeouts, manually interrupted tasks, cancellation of ongoing operations and so on - and that for each and every possible operation. The result was that most things worked in most situations, but there remained a big gray area of rarely encountered combinations of events.

Now, the new vibe-core package aims to streamline all of this as much as possible, while staying mostly backwards compatible to the original core package, from a library user's point of view. A new shallow event loop abstraction, eventcore, has been implemented to avoid the reliance on external C libraries and to be able to quickly prototype possible performance optimizations.

The task scheduling logic has been encapsulated into a single generic function that correctly handles all the various possible courses of action in a unified way. This means that there are no more gray areas and only a single central piece of code that focuses solely on the scheduling logic has to be maintained. The rest of the code base has been modernized, following the language developments since 2012:

  • Streams can now be implemented as structs, too, and most places that accept a stream do so in a generic way, meaning that the static type of the stream is known and consequently enabling the elimination of virtual function calls, as well as enabling function inlining and of course avoiding the GC allocations otherwise needed to create a class instances.

  • A new IOMode parameter allows to simulate the behavior of classical blocking or non-blocking socket operations. This makes it much easier to port existing socket based code by avoiding the need to use vibe.d specific primitives, such as .leastSize or .dataAvailableForRead.

  • All event objects (File, TCPConnection etc.) are now implemented as reference counting structs, with their payload stored in a compact array together with low-level control data of the event loop abstraction. Consequently, no dynamic memory allocations happen anymore when objects are created or destroyed.

  • @safe and nothrow have been added where possible throughout the whole code base. @nogc has also been added, but only in some limited places due to its viral nature and the fact that user supplied callbacks are involved in many places.

  • Instead of a single path type that tries to handle all possible path formats, three statically typed and validated path types have been implemented: PosixPath, WindowsPath and InetPath, with an additional NativePath alias that means either WindowsPath or PosixPath depending on the target platform.

To ensure a smooth transition, the new core package is still disabled by default in version 0.8.0 of vibe.d, which is being released simultaneously. Once the stability of the new system has been proven sufficiently in production, this default will be switched to the new one. Still, for anyone who can afford it, it is highly recommended to start testing and using the new module as early as possible. It can be enabled by selecting the "vibe-core" configuration of the vibe-d:core module:

// in dub.sdl add:
dependency "vibe-d:core" version="~>0.8.0"
subConfiguration "vibe-d:core" "vibe-core"
// in dub.json add:
{
	...
	"dependencies" : {
		...
		"vibe-d:core": "~>0.8.0"
	},
	"subConfigurations": {
		...
		"vibe-d:core": "vibe-core"
	}
}

You can find the new vibe-core package on GitHub, as well as on the DUB registry:

Posted at 10:37:56 +0200 by Sönke Ludwig

0 comments