• Stars
    star
    957
  • Rank 47,756 (Top 1.0 %)
  • Language
    Ruby
  • License
    Other
  • Created almost 12 years ago
  • Updated almost 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Reactive Extensions for Ruby

Build Status GitHub version Downloads Code Climate

The Need to go Reactive | About the Reactive Extensions | Why RxRuby? | Contributing | License

The Reactive Extensions for Ruby (RxRuby) 0.1...

...is a set of libraries to compose asynchronous and event-based programs using observable collections and Enumerable module style composition in Ruby

The Need to go Reactive

Reactive Programming is a hot topic as of late, especially with such things as the Reactive Manifesto. Applications' needs have changed over time, from simple polling for data to a full reactive system where data is pushed at you. Each time, we're adding more complexity, data, and asynchronous behavior to our applications. How do we manage it all? How do we scale it? By moving towards "Reactive Architectures" which are event-driven, resilient, and responsive. With the Reactive Extensions, you have all the tools you need to help build these systems.

About the Reactive Extensions

The Reactive Extensions for Ruby (RxRuby) is a set of libraries for composing asynchronous and event-based programs using observable sequences and fluent query operators that many of you already know in Ruby. Using RxRuby, developers represent asynchronous data streams with Observables, query asynchronous data streams using our many operators, and parameterize the concurrency in the asynchronous data streams using Schedulers. Simply put, RxRuby = Observables + Operators + Schedulers.

When you're authoring applications with Ruby, there may be times when you want to deal with asynchronous and event-based programming, and synchronization is difficult and error prone.

Using RxRuby, you can represent multiple asynchronous data streams (that come from diverse sources, e.g., stock quotes, tweets, computer events, web service requests, etc.), and subscribe to the event stream using the Observer module. The Observable notifies the subscribed Observer instance whenever an event occurs.

Because observable sequences are data streams, you can query them using standard query operators implemented by the Observable module. Thus you can filter, project, reduce, compose, and perform time-based operations on multiple events easily by using these operators. In addition, there are a number of other reactive stream-specific operators that allow powerful queries to be written. Cancellation, exceptions, and synchronization are also handled gracefully by using the methods on the Observable module.

But the best news of all is that you already know how to program like this. Take for example the following Ruby code, where we get some stock data, manipulate it, and then iterate over the results.

# Get evens and square each
someSource
  .select { |x| x.even? }
  .map { |x| x * x }
  .each { |x| puts x.to_s }

Using RxRuby, you can accomplish the same kind of thing with a push-based collection by changing each to subscribe.

someSource
  .select { |x| x.even? }
  .map { |x| x * x }
  .subscribe { |x| puts x.to_s }

Why RxRuby?

The overall goal of RxRuby is to have a push-based version of the Enumerable module with an added notion of time. Right now, the Observable module is not quite what we want because it does not allow for composition. That is no more than a simple implementation of the Subject/Observer pattern from the Gang of Four book, such as the following.

require 'observer'

class ArrayObservable
  include Observable

  def initialize(array)
    @array = array
  end

  def run
    index = 0

    while index < @array.length
      change #notify of change
      notify_observers @array[index] # send the current value
      index += 1
      sleep 1
    end
  end
end

class ArrayObserver
  def initialize(observable)
    observable.add_observer(self)
  end

  def update(item)
    puts item.to_s
  end
end

observable = ArrayObservable [1,2]
observer = ArrayObserver.new(observable)
# 1
# 2

But how do you enable better composition so that you can compose together Observable instances? In this current model, this can't happen. That's why we need the Reactive Extensions for Ruby. Not only that, we can, at any point in the computation, change the concurrency model to be immediate, on a new thread, or on another machine.

There are many implementations of the Reactive Extensions such as RxJS, Rx.NET, Java/JVM/Clojure/Scala/JRuby/Groovy and ObjC/ReactiveCocoa. Our goal is to have one operate like the JRuby one, but be available to all users of Ruby, regardless of VM.

We'd like it to be like our JavaScript version, RxJS but be able to handle multi-threading, parallelism, and in addition, go across the network.

Instead, our goal is to make the Observable module look exactly like the Enumerable module, in that you can write any query method over it to produce a value, but have it push-based. This could become yet another competitor to EventMachine, in which we have rich composition over events, whether locally or across the network.

So, take an example, zipping two Arrays.

a = [4, 5, 6]
b = [7, 8, 9]

[1, 2, 3].zip(a, b)      #=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
[1, 2].zip(a, b)         #=> [[1, 4, 7], [2, 5, 8]]
a.zip([1, 2], [8])       #=> [[4, 1, 8], [5, 2, nil], [6, nil, nil]]

Now, we could do something similar in RxRuby with two observable sequences:

require 'rx'

a = Rx::Observable.from_array [4, 5, 6]
b = Rx::Observable.from_array [7, 8, 9]

sub = a.zip(b).subscribe { |arr| puts arr.to_s }
# => "[4, 7]"
# => "[5, 8]"
# => "[6, 9]"

# unsubscribes from the sequence and cleans up anything
sub.unsubscribe

The difference here is that zip returns an Rx::Observable instead of an Enumerable. And once you call subscribe it's much like each but takes an observer, or perhaps just some blocks, lambdas, etc. The subscription handed back contains the cancellation logic. For example, if you are listening to events and you no longer want to listen, you can call unsubscribe on the sub variable above.

What's the end goal? The first part is that we want to support the main Enumerable module methods in the Observable module and have them react the same way, but push instead of pull-based. From there, we can explore such things as multi-threading, and calls across the network.

If you want to find out more, please check out the JavaScript version, RxJS, which has more details on the overall goals.

Our overall goal is to make this one of the best Rx libraries out there, better than RxJS, RxPy, ReactiveCocoa, RxJava, etc, all while maintaining the "Ruby Way".

Contributing

You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.

License

Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

More Repositories

1

RxJava

RxJava โ€“ Reactive Extensions for the JVM โ€“ a library for composing asynchronous and event-based programs using observable sequences for the Java VM.
Java
47,865
star
2

rxjs

A reactive programming library for JavaScript
TypeScript
30,686
star
3

RxSwift

Reactive Programming in Swift
Swift
24,267
star
4

RxAndroid

RxJava bindings for Android
Java
19,889
star
5

RxKotlin

RxJava bindings for Kotlin
Kotlin
7,036
star
6

RxGo

Reactive Extensions for the Go language.
Go
4,921
star
7

RxPY

ReactiveX for Python
Python
4,775
star
8

rxdart

The Reactive Extensions for Dart
Dart
3,338
star
9

RxCpp

Reactive Extensions for C++
C++
3,008
star
10

RxPHP

Reactive extensions for PHP
PHP
1,685
star
11

learnrx

A series of interactive exercises for learning Microsoft's Reactive Extensions Library for Javascript.
JavaScript
1,403
star
12

RxNetty

Reactive Extension (Rx) Adaptor for Netty
Java
1,384
star
13

IxJS

The Interactive Extensions for JavaScript
TypeScript
1,297
star
14

RxScala

RxScala โ€“ Reactive Extensions for Scala โ€“ a library for composing asynchronous and event-based programs using observable sequences
Scala
888
star
15

RxJavaFX

RxJava bindings for JavaFX
Java
520
star
16

RxRust

The Reactive Extensions for the Rust Programming Language
Rust
488
star
17

RxClojure

RxJava bindings for Clojure
Clojure
362
star
18

rxjs-tslint

TSLint rules targeting RxJS
TypeScript
309
star
19

RxJavaReactiveStreams

Adapter between RxJava and ReactiveStreams
Java
235
star
20

RxJavaDebug

Java
161
star
21

rxjs-docs

The home for new work on the new RxJS docs (RxJS v 5 and up). New to this space? Say hi here: https://github.com/ReactiveX/rxjs-docs/issues/24. Want to find out what's up? We're chatting here. https://github.com/ReactiveX/rxjs-docs/issues/4
TypeScript
160
star
22

RxGroovy

RxJava bindings for Groovy
Groovy
158
star
23

reactivex.github.io

ReactiveX Website
JavaScript
139
star
24

RxJavaAsyncUtil

Java
132
star
25

RxJavaString

Java
129
star
26

RxApacheHttp

RxJava bindings for Apache HTTP
Java
118
star
27

RxJavaJoins

Java
100
star
28

RxSwing

RxJava bindings for Swing
Java
98
star
29

RxJavaMath

Math operators for RxJava.
Java
96
star
30

rxjs-advent-2018

RxJS 2018 Advent Calendar
TypeScript
89
star
31

rxjs-core-notes

Notes from RxJS core meetings
77
star
32

RxJavaFileUtils

File utilities with RxJava
Java
62
star
33

RxJavaComputationExpressions

Java
60
star
34

RxJavaGuava

Java
54
star
35

RxJavaParallel

Experimental Parallel Extensions for RxJava
Java
54
star
36

RxJRuby

RxJava bindings for JRuby
Ruby
38
star
37

Rx.NET

Rx.NET โ€“ Reactive Extensions for .NET โ€“ a library for composing asynchronous and event-based programs using observable sequences for the CLR.
31
star
38

RxQuasar

RxJava bindings for Quasar
Java
16
star
39

RxRoboVM

RxJava bindings for iOS
Java
7
star
40

BuildInfrastructure

Test project for the new build system.
Groovy
5
star
41

RxSwing2

Reactive bindings for Java 8 Swing on top of RxJava 2
4
star