RubyConf 2015

Desarrollando librerías Ruby concurrentes

Petr Chalupa  · 




Extracto de la transcripción automática del vídeo realizada por YouTube.

- Good evening, everyone. Thanks for coming. My name is Petr Chalupa, I'm with Oracle Labs, and I work on a project called JRuby+Truffle there. Let me first just make sure that you understand that JRuby+Truffle is just a research project at Oracle Labs, it has nothing to do with Oracle products.

And any opinions expressed in this talk are my own. So, let me start by introducing two projects, which we'll touch in this presentation. The first one is called Concurrent Ruby. So, basically, unopinionated collection of high level and low level concurrent up sections.

And unopinionated means that we are not trying to force any solution on you, you can choose the best solution which works for your particular problem. We support MRI, JRuby, Rubinius, and we're also working on support for JRuby+Truffle right now. And this gem is already used in Rails 5, Sucker Punch, Dynflow, and many more projects.

And we've just released a 1. 0 version, so, it's a great amount done for us. For the high level abstractions, we have, for example, chain-able futures, going by channels, extras, Clojure inspired agent software transactional memory, and more. We have to make references that say that the structures have some low level synchronization primitives like CountDownLatch, Semaphore, CyclicBarrier, and stuff like that, which helps you to create another concurrent of sections more easier.

And the second project, which was already mentioned, is JRuby+Truffle, which is experimental back hand in JRuby. And it's part of the same repository. So, it's open source. It's basically an AST interpreter, but the key thing is that it's a self-optimizing up stack syntax interpreter, which means that as it, this interpreter executes your code, it can profile which benches where they come, or what types it's on, and based off of that, the nodes can specialize.

And after some time, this tree of nodes, we can assume that it's stable, and we can feed it to a ground compiler. It can then produce a highly optimized machine call for us. If some of these optimize assumptions fail, then we can invalidate the compiled code, which was railing on those assumptions, go back to the interpreter at that point, let it run some more, specialize again, and again compile.

So, this is basically the gist of why JRuby+Truffle is quite fast, and we will see some of the results. The main support, the JRuby+Truffle support is wholly pivotal to any restrictions, it also supports the tricky ones like debugging, set trace function, object space.

We also, you don't also need any options to turn them on, they are always on, and they don't have any overhead if you are not using them. They are at about 90% compatibility based on our Ruby specs. And as I mentioned, it's part of the same repository as JRuby, so it's also part of the distribution already, so if you add option X plus T, you can already try some micro benchmarks, solve with more projects, and we already run some of the gems, which are listed at the bottom.

So now, let's move to the main topic of this talk, which is implementing a concurrent abstraction. So, let me start talking a little bit about why concurrency is actually difficult. So, the main reason is that processors and compiles are free to reorder, in which our code is actually executed.

As long as they keep sequential consistency and you don't tell the compiler that you don't want some pieces to be reordered. And you may think that it would be good to just prohibit this behavior, but actually, this is very desirable because compiler and processor may do lots of optimizations due to these arrow settings.

So, you cannot just forbid it. But the result is that another thread may see very strange values because on thread A, the code is actually executed in different order than we wrote it, so it writes these, writes to the memory in a different order. So, the page will actually tell reasons on how about this, we have to consider other possible variable, sorry, other possible valid orders in which our code can be executed.

And to be able to construct these orders, we have to have some kind of framework to be able to figure them out, which is called memory model, and I will touch, I will talk about it a little bit later. And of course, this is a great train packed on JRuby because, sorry, on JRuby+Truffle because JRuby+Truffle is able to optimize your Ruby code, and to mark much less instructions, so you can actually observe these effects of reordering more often.

So, let me show you some example of what can happen. So, this example, we have a simple class with just one field value, and we will be assigning a new instance of this class to the local variable. So, we have here two writes to the memory, this is the first one and here is the second one.

So, and we are reading them both here on the line 17. So, if compiler tries to optimize this, it can see that it doesn't matter in which order these two writes are executed, so it can actually switch them. But if that happens, in this write, you can actually observe that you, that the instance was already filled, but the value wasn't because the other was fixed, so this can actually write an exception.

[ ... ]

Nota: se han omitido las otras 2.591 palabras de la transcripción completa para cumplir con las normas de «uso razonable» de YouTube.