All Projects → imkira → go-observer

imkira / go-observer

Licence: MIT license
Go package for simplifying channel-based broadcasting of events from multiple publishers to multiple observers

Programming Languages

go
31211 projects - #10 most used programming language
Makefile
30231 projects

Projects that are alternatives of or similar to go-observer

laravel-attribute-observer
Observe (and react to) attribute changes made on Eloquent models.
Stars: ✭ 59 (-10.61%)
Mutual labels:  events, observer
Observable
minimalist event system for Python
Stars: ✭ 66 (+0%)
Mutual labels:  events, observer
EventEmitter
Simple EventEmitter with multiple listeners
Stars: ✭ 19 (-71.21%)
Mutual labels:  events, observer
Ease
It's magic.
Stars: ✭ 1,213 (+1737.88%)
Mutual labels:  events, observer
transceiver
Channel based event bus with request/reply pattern, using promises. For node & browser.
Stars: ✭ 25 (-62.12%)
Mutual labels:  events, channels
channels
go channel patterns
Stars: ✭ 86 (+30.3%)
Mutual labels:  channels
Protobuf-Dreamer
A tiled DeepDream project for creating any size of image, on both CPU and GPU
Stars: ✭ 39 (-40.91%)
Mutual labels:  channels
echo-server
Echo Server is a Docker-ready, multi-scalable Node.js application used to host your own Socket.IO server for Laravel Broadcasting.
Stars: ✭ 32 (-51.52%)
Mutual labels:  broadcasting
uevloop
A fast and lightweight event loop for embedded platforms.
Stars: ✭ 61 (-7.58%)
Mutual labels:  events
public-speaking
🎤 List of presentation, volunteer and initiatives
Stars: ✭ 11 (-83.33%)
Mutual labels:  events
patterns
Good practices to create code in Java, open to other languages. ⚡
Stars: ✭ 14 (-78.79%)
Mutual labels:  observer
watermill-nats
NATS Pub/Sub for the Watermill project.
Stars: ✭ 25 (-62.12%)
Mutual labels:  events
dewdle
A remote video-feed drawing tool (telestrator) for streaming and broadcast environments.
Stars: ✭ 29 (-56.06%)
Mutual labels:  broadcasting
SwiftObserver
Elegant Reactive Primitives for Clean Swift Architecture #NoRx
Stars: ✭ 14 (-78.79%)
Mutual labels:  observer
gancio
a shared agenda for local communities (with activitypub support)
Stars: ✭ 21 (-68.18%)
Mutual labels:  events
TensorCast.jl
It slices, it dices, it splices!
Stars: ✭ 106 (+60.61%)
Mutual labels:  broadcasting
soketi
Just another simple, fast, and resilient open-source WebSockets server. 📣
Stars: ✭ 2,202 (+3236.36%)
Mutual labels:  broadcasting
sdk-python
Python SDK for CloudEvents
Stars: ✭ 149 (+125.76%)
Mutual labels:  events
continuous-analytics-examples
A collection of examples of continuous analytics.
Stars: ✭ 17 (-74.24%)
Mutual labels:  events
dynamic-engine
Monitor events in the background on Android.
Stars: ✭ 24 (-63.64%)
Mutual labels:  events

observer

License GoDoc Build Status Coverage codebeat badge goreportcard

observer is a Go package that aims to simplify the problem of channel-based broadcasting of events from one or more publishers to one or more observers.

Problem

The typical quick-and-dirty approach to notifying a set of observers in go is to use channels and call each in a for loop, like the following:

for _, channel := range channels {
  channel <- value
}

There are two problems with this approach:

  • The broadcaster blocks every time some channel is not ready to be written to.
  • If the broadcaster blocks for some channel, the remaining channels will not be written to (and therefore not receive the event) until the blocking channel is finally ready.
  • It is O(N). The more observers you have, the worse this loop will behave.

Of course, this could be solved by creating one goroutine for each channel so the broadcaster doesn't block. Unfortunately, this is heavy and resource-consuming. This is especially bad if you have events being raised frequently and a considerable number of observers.

Approach

The way observer package tackles this problem is very simple. For every event, a state object containing information about the event, and a channel is created. State objects are managed using a singly linked list structure: every state points to the next. When a new event is raised, a new state object is appended to the list and the channel of the previous state is closed (this helps notify all observers that the previous state is outdated).

Package observer defines 2 concepts:

  • Property: An object that is continuously updated by one or more publishers.
  • Stream: The list of values a property is updated to. For every property update, that value is appended to the list in the order they happen, and is only discarded when you advance to the next value.

Memory Usage

The amount of memory used for one property is not dependent on the number of observers. It should be proportional to the number of value updates since the value last obtained by the slowest observer. As long as you keep advancing all your observers, garbage collection will take place and keep memory usage stable.

How to Use

First, you need to install the package:

go get -u github.com/imkira/go-observer

Then, you need to include it in your source:

import "github.com/imkira/go-observer"

The package will be imported with observer as name.

The following example creates one property that is updated every second by one or more publishers, and observed by one or more observers.

Documentation

For advanced usage, make sure to check the available documentation here.

Example: Creating a Property

The following code creates a property with initial value 1.

val := 1
prop := observer.NewProperty(val)

After creating the property, you can pass it around to publishers or observers as you want.

Example: Publisher

The following code represents a publisher that increments the value of the property by one every second.

val := 1
for {
  time.Sleep(time.Second)
  val += 1
  fmt.Printf("will publish value: %d\n", val)
  prop.Update(val)
}

Note:

  • Property is goroutine safe: you can use it concurrently from multiple goroutines.

Example: Observer

The following code represents an observer that prints the initial value of a property and waits indefinitely for changes to its value. When there is a change, the stream is advanced and the current value of the property is printed.

stream := prop.Observe()
val := stream.Value().(int)
fmt.Printf("initial value: %d\n", val)
for {
  select {
    // wait for changes
    case <-stream.Changes():
      // advance to next value
      stream.Next()
      // new value
      val = stream.Value().(int)
      fmt.Printf("got new value: %d\n", val)
  }
}

Note:

  • Stream is not goroutine safe: You must create one stream by calling Property.Observe() or Stream.Clone() if you want to have concurrent observers for the same property or stream.

Example

Please check examples/multiple.go for a simple example on how to use multiple observers with a single updater.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].