Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,583
|
Comments: 51,213
Privacy Policy · Terms
filter by tags archive
time to read 5 min | 867 words

imageNext week is CodeMash, in Ohio. I’m going to be at the conference and I have a talk about extreme performance architecture. I’m going to try to condense in 45 minutes the lessons that took us a decade to learn and almost two years to implement. That should be fun, but as much as I enjoy speaking, it is the first time in a while that I’m actually going to go to a conference, not just be there at the booth, and that is really exciting for me.

I took a look at the schedule and there are some interesting workshops and sessions.

Without any particular order, here are the things that popped out as stuff that I would like to be at

BTW, to the CodeMash people, not being able to link directly to the sessions is a PITA.

Workshops:

  • Up & Running with Graph Databases - Greg Jordan – I would love to get a feel to how things are looking from the side consuming the graph API, not the one implementing it. If all goes well, I might do a series of posts on the exercises in the workshop as it pertains to RavenDB.
  • CodeMash CryptoParty - Dusty Burwell – I have a love/hate relationship with cryptography. I find it fascinating but the math is usually beyond me,  so I can’t understand it (that’s a joke).

Sessions:

  • Making and Baking an Application Security Department - Bill Sempf – Following up on the crypto party, this is an are that I care deeply about, so it is worth the 8AM timeslot to learn more about this. I’m also interested in how I can, as an infrastructure, meaningfully contribute to the application overall security.
  • 7 Reasons why your microservices should use Event Sourcing & CQRS - Hugh McKee – I’m familiar with both CQRS and microservices, but putting them together seems interesting. I’m mostly wondering about the data flow paths in such a system as the data is required on multiple servers.
  • "Did you get my message?" - A comparison of several modern messaging platforms - Jack Bennett – This is very close to what I usually do, and I went over ZeroMQ’s code a few time, so that would be interesting.
  • Building a better audit log - Craig Hills – this is a pain point in many cases, what to log and how, and the tension between logging too much and too little.
  • Database DevOps with Containers - Rob Richardson – I think that my interest in this one is pretty obvious Smile.
  • Bluetooth Prototyping with the Raspberry Pi – I’m using my Raspberry Pis to run clusters of database servers, I wonder if there are other possible uses for a 25$ machine…
  • Extreme Performance Architecture - Oren Eini – I’m giving this talk, so I guess I gotta.
  • Pivot: How to proceed when things don't work out - Jay Harris – This is in the same timeslot as I’m speaking at, but I would have like to listen to it. Failure, planning for failure and recovering from it are all very important skills.
  • ZAPping Security Vulnerabilities in Your Development Pipeline - Matthew Smith – This seems like it would be a session that cover an eminently useful skill.
  • My users posted what? - Harold Pulcher – I don’t have a direct use for the topics discussed here, but it seems interesting, and I like learning for leaning sake. At some future time, it always pays off.
  • APIs on the Scale of Decades - Gary Fleming - RavenDB is ten years old, and I’m certainly feeling the pressure there.
  • THE STORIES OF THE MOST INFAMOUS BUGS - Ian Zelikman – Because who doesn’t want to see a clown slip on a banana peel, and this is the high tech equivalent.
  • Data management in a Microservices world - Gerald Venzl – This is a topic that I have been thinking a lot about, and more information there would be very useful.
  • Patterns and Architectures Beyond Microservices - Stephen Shary – should be interesting, some of the patterns that are mentioned in the description aren’t known to me and I have to exert some willpower not to search for them and wait for the session.
  • Post Mortem: Dealing with Failure in Development - BJ Burns – Already said that this is an important topic, so this session is also very intereseting.
  • Building A Highly Scalable Service that Survived A Super Bowl - Keith Elder – Because if nothing else, the story is likely going to be awesome.
  • Comments are Useless and Other Controversial Opinions About Code - Izzi Bikun – This sounds like a fun session.

There are a lot of other stuff there that looks good, and I don’t even know if I’ll be able to get through all these sessions (not actually possible, there are timing conflicts between some of them). But the point of the conference isn’t just to sit in the sessions but the hallway interactions and actually talking with people.

I’m looking forward to that and I’m bringing a few books and some swag as well, if anyone is there and is interested.

I’m really looking forward to it.

time to read 4 min | 757 words

The next interesting step in my Rust network protocol exercise is to implement TLS. I haven’t looked at that yet, so it is going to be interesting.

The first search for “Rust TLS” gives me the rustls project, which seems to provide a native Rust implementation. There are also native-tls, which uses the system TLS library and binding for OpenSSL. I’m not sure how trust worthy rustls is, but I’m building a network protocol that is meant as an exercise, so I don’t really care. The first thing that I wanted to write was pretty trivial. Just convert the current code to use TLS on the wire, nothing more.

I wrote the following code to set things up:

There is a lot going on and I spend some time figuring out exactly what needs to be done here. I’m kinda proud / kinda scared of this code. It is packed. But on the other hand, if you read it, it is fairly clear, it is just that it does a lot of stuff.

I then used this in the following way:

image

And that led to this error when using OpenSSL to connect to it:

image

On the rust side, it died with:

image

The good thing, both sides agree that there is a handshake issue, but I had no idea what was going on. The bad thing, I have no clue why this is failing. According to the docs, this is supposed to work. I tried debugging into rustls and it seems to be failing very early in the handshake process, but I’m not familiar enough with either Rust or TLS to really understand why. The core issues seems to be here:

image

Note that we get a payload of None, but when I’m debugging through the code in the read_version method, it seems like it returns properly.

Oh, I figured it out, the issue is here:

image

Note the highlighted section? If this returns a None, it will silently return from the method. It is easy to miss something like that. Digging (much) deeper, I found:

image

And deeper still, we have:

image

Go back a bit and see what kind of URL I gave to OpenSSL, it was 127.0.0.1, and it seems like rustls doesn’t support raw IPs, only hostnames. The limit seems to be the result of this code:

image

This seems to be a known error, it is opened since May 2017 and it is a completely deal breaker for me. I’m guessing that this isn’t a big issue in general because usually if you have a cert, it is for a hostname and certificates for IPs (which exists, but tend to be issued for private CAs) are far rarer.

I changed my cmd line to use:

image

And it started working, but at that point, I was debugging this issue for over an hour, so that is quite enough for today.

As an aside, I was able to attach to the rust process using Visual Studio and debug it fairly normally. There is some weirdness that I believe relates to the cleanup, where if you abort a method early it looks like it goes back in time until it exit the method. However, overall it works fairly nicely. I do have to point out that many of the nicer features in the language are making debugging much harder.

That said, once thing was absolutely amazing and it was the fact that I was so easily debug into my dependencies, in fact, I was changing the code of my dependencies and re-running it, to help me narrow down exactly where the error was. That was easy, obvious and worked. Very nice!

time to read 5 min | 841 words

After spending a lot of time writing my network protocol in C, I decided that it would be a nice exercise to do the same in Rust. I keep getting back to this language because I want to like it. I hope that having a straightforward task and the passage of time will make things easier than before.

I gotta say, the compiler feels a lot nicer now. Check this out:

image

I really like it. This feels like the compiler is actively trying to help me get in the right path…

And this error message made me even happier:

image

Thank you, this is clear, concise and to the point.

I can indeed report that the borrow checker is indeed very much present, but at least now it will tell you what is the magic incantation you need to make it happen:

image

This is my third or forth foray into Rust, and I stopped a few times before because the learning curve and the… Getting Things Done curve were just weren’t there for me. In this case, however, I’m getting a very different feel all around. There is a lot less messing around and a lot more actually getting to where I want to go. I’m still significantly slower, naturally, since I’m learning idioms and the mechanics of the language, but there is a lot less friction. And the documentation has been top notch, and I’m leaning on that a lot.

In particular, one of my pet peeves seems to have been resolved. Composite error handling is now as simple as:

 

Removing the ceremony from error handling is a great relief, I have to say.

It took me a couple of evenings to get to the point where I can setup a TCP server, accept a connection and parse the command. Let me see if I can break it up to manageable parts, even though the whole thing is about 100 lines of code, this is packed.

I’m certainly feeling the fact that Rust actually have a runtime library. I mean, C has one, but it is pretty anemic to say the least. And actually having an OOTB solution for packaging is not really an option today, it is a baseline requirement.

Here is the code that handles the connection itself.

By itself, it is pretty simple. It starts by letting the client know that we are ready (the OK msg) and then read a message from the client, parse it and dispatch it. Rinse, repeat, etc.

There are a couple of interesting things going on here that might be worth your attention:

  • The read_full_message() function works on bytes, and it is responsible for finding the message boundaries. The code is meant to handle pipelined messages, partial reads, etc.
  • Once we have the range of bytes that represent a single message, we translate them to UTF8 string and use string processing to parse the command. This is simpler than the tokenization we did in C.
  • After processing a message, we drain the data we already process and continue with the data already in the buffer. Note that we basically reuse the same buffer, so hopefully there shouldn’t be too many allocations along the way.

The buffer handling is the responsibility of the read_full_message() function, which looks like:

I’m using an inefficient method, where I’m reading only 256 bytes at a time from the network, mostly to prove that I can process things that come over in multiple calls. But the basic structure is simple:

  • Use TwoWaySearcher to search for a byte pattern in the buffer. This is basically memmem() call.
  • If the byte pattern (\r\n\r\n) is found, we have a message boundary and can return that to the caller.
  • If the message boundary isn’t found, we need to read more data from the network.
  • I’m playing some tricks with the to_scan variable, avoiding the case where I need to scan over data that I have already scanned.
  • I’m also validating that I’m never reading too much from the network and abort the connection if we can’t find the message boundary in a reasonable size (8KB).

What remains is some string parsing, which ended up being really easy, since Rust has normal string processing routines.

And this is pretty much it, I gotta say. For that amount of code, it took a long time to get there, but I’m pretty happy with the state of the code. Of course, this is still pretty early in the game and it isn’t really doing anything really interesting. The TCP server can accept only a single connection (breaking the connection will kill the server, at this point), error handling is the same as not having a single catch in the entire system, etc.

What I expect to be… interesting is the use of SSL and concurrent (hopefully async) I/O. We’ll see where that will take us…

FUTURE POSTS

No future posts left, oh my!

RECENT SERIES

  1. Production postmorterm (2):
    11 Jun 2025 - The rookie server's untimely promotion
  2. Webinar (7):
    05 Jun 2025 - Think inside the database
  3. Recording (16):
    29 May 2025 - RavenDB's Upcoming Optimizations Deep Dive
  4. RavenDB News (2):
    02 May 2025 - May 2025
  5. Production Postmortem (52):
    07 Apr 2025 - The race condition in the interlock
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats
}