All Projects → servicetitan → Stl.fusion

servicetitan / Stl.fusion

Licence: mit
Get real-time UI updates in Blazor apps and 10-1000x faster API responses with a novel approach to distributed reactive computing. Fusion brings computed observables and automatic dependency tracking from Knockout.js/MobX/Vue to the next level by enabling a single dependency graph span multiple servers and clients, including Blazor apps running in browser.

Projects that are alternatives of or similar to Stl.fusion

Sandstone
PHP microframework designed to build a RestApi working together with a websocket server. Build a real time RestApi!
Stars: ✭ 98 (-88.58%)
Mutual labels:  websockets, real-time, realtime, websocket-server
Beast
HTTP and WebSocket built on Boost.Asio in C++11
Stars: ✭ 3,241 (+277.74%)
Mutual labels:  websockets, websocket-server, websocket-client
LazWebsockets
Websocket Server and Client Library written in Lazarus
Stars: ✭ 51 (-94.06%)
Mutual labels:  websocket-server, websockets, websocket-client
Ulfius
Web Framework to build REST APIs, Webservices or any HTTP endpoint in C language. Can stream large amount of data, integrate JSON data with Jansson, and create websocket services
Stars: ✭ 666 (-22.38%)
Mutual labels:  websockets, websocket-server, websocket-client
intrinio-realtime-python-sdk
Intrinio Python SDK for Real-Time Stock Prices
Stars: ✭ 79 (-90.79%)
Mutual labels:  real-time, websockets, realtime
text
An experiment with WebSockets and the human condition.
Stars: ✭ 51 (-94.06%)
Mutual labels:  websocket-server, websockets, websocket-client
Websocket Client
🔧 .NET/C# websocket client library
Stars: ✭ 297 (-65.38%)
Mutual labels:  websockets, websocket-client, dotnet-core
Websocat
Command-line client for WebSockets, like netcat (or curl) for ws:// with advanced socat-like functions
Stars: ✭ 3,477 (+305.24%)
Mutual labels:  websockets, websocket-server, websocket-client
Saea
SAEA.Socket is a high-performance IOCP framework TCP based on dotnet standard 2.0; Src contains its application test scenarios, such as websocket,rpc, redis driver, MVC WebAPI, lightweight message server, ultra large file transmission, etc. SAEA.Socket是一个高性能IOCP框架的 TCP,基于dotnet standard 2.0;Src中含有其应用测试场景,例如websocket、rpc、redis驱动、MVC WebAPI、轻量级消息服务器、超大文件传输等
Stars: ✭ 318 (-62.94%)
Mutual labels:  websockets, websocket-client, high-performance
Cowboy
Small, fast, modern HTTP server for Erlang/OTP.
Stars: ✭ 6,533 (+661.42%)
Mutual labels:  websockets, websocket-server, high-performance
Websocket Manager
Real-Time library for ASP .NET Core
Stars: ✭ 400 (-53.38%)
Mutual labels:  websockets, real-time, dotnet-core
remoting
Jetlang Remoting - asynchronous distributed messaging
Stars: ✭ 27 (-96.85%)
Mutual labels:  websocket-server, websockets, websocket-client
soketi
Just another simple, fast, and resilient open-source WebSockets server. 📣
Stars: ✭ 2,202 (+156.64%)
Mutual labels:  real-time, websockets, realtime
reactive-streams-for-java-developers
No description or website provided.
Stars: ✭ 16 (-98.14%)
Mutual labels:  websocket-server, websockets, websocket-client
channeled-dashboard
Repository for the talk `Building real time applications with Django and Channels`
Stars: ✭ 20 (-97.67%)
Mutual labels:  websocket-server, websockets, realtime
Ws
Simple to use, blazing fast and thoroughly tested WebSocket client and server for Node.js
Stars: ✭ 17,419 (+1930.19%)
Mutual labels:  real-time, websocket-server, websocket-client
Sylar
C++高性能分布式服务器框架,webserver,websocket server,自定义tcp_server(包含日志模块,配置模块,线程模块,协程模块,协程调度模块,io协程调度模块,hook模块,socket模块,bytearray序列化,http模块,TcpServer模块,Websocket模块,Https模块等, Smtp邮件模块, MySQL, SQLite3, ORM,Redis,Zookeeper)
Stars: ✭ 895 (+4.31%)
Mutual labels:  websocket-server, websocket-client, high-performance
Php Wss
Web-socket server/client with multi-process and parse templates support on server and send/receive options on client
Stars: ✭ 117 (-86.36%)
Mutual labels:  websockets, websocket-server, websocket-client
Ixwebsocket
websocket and http client and server library, coming with ws, a command line swiss army knife utility
Stars: ✭ 204 (-76.22%)
Mutual labels:  websockets, websocket-server, websocket-client
Websockets
Library for building WebSocket servers and clients in Python
Stars: ✭ 3,724 (+334.03%)
Mutual labels:  websockets, websocket-server, websocket-client

All project updates are published on its Discord Server; it's also the best place for Q/A.
Build Coverage NuGet Version

What is Fusion?

MIT License Commit Activity Downloads Discord Server

Fusion is a .NET 5 / .NET Core 3.1 library providing a new change tracking abstraction built in assumption that every piece of data you have is a part of the observable state / model, and since there is no way to fit such a huge state in RAM, Fusion:

  • Spawns the observed part of this state on-demand
  • Holds the dependency graph of any observed state in memory to make sure every dependency of this state triggers cascading invalidation once it gets changed.
  • And finally, it does all of this automatically and transparently for you, so Fusion-based code is almost identical to the code you'd write without it.

This is quite similar to what any MMORPG game engine does: even though the complete game state is huge, it's still possible to run the game in real time for 1M+ players, because every player observes a tiny fraction of a complete game state, and thus all you need is to ensure this part of the state fits in RAM + you have enough computing power to process state changes for every player.

Under the hood, Fusion turns any response of your internal and public API into ~ (Result<T> Response, Task Invalidated) pair, where the second part tells when this pair has to be recomputed. But you rarely need to deal with this – Fusion-based services return regular result types, and these pairs (actually, IComputed<T> instances) are created, consumed, and composed into complex dependency graphs transparently for you.

Build a Real-Time UI

This is Fusion+Blazor Sample, delivering real-time updates to 3 browser windows:

The sample supports both (!) Server-Side Blazor and Blazor WebAssembly hosting modes – you can switch the mode on its "Home" page.

Play with live version of this sample right now!

Check out Board Games - the newest Fusion sample that implements both Blazor Server and WASM modes, 2 games, chat, online presence, OAuth sign-in, user session tracking, and a number of other 100% real-time features. All of this is powered by Fusion + just 35 lines of code related to real-time updates!

Read "Why real-time UI is inevitable future for web apps?" to learn why "Refresh" is so obsolete nowadays.

Speedup Your Service By Caching Everything

A small benchmark in Fusion test suite compares "raw" Entity Framework Core - based Data Access Layer (DAL) against its version relying on Fusion. Both tests run almost identical code - in fact, the only difference is that Fusion version of this test uses Fusion-provided proxy wrapping the UserService (the DAL used in this test) instead of the actual type.

The performance difference looks shocking at first:

The speedup is:

Such a speedup is possible because Fusion ensures that every output Fusion service produces or consumes – even the intermediate one – is computed just once and reused without recomputation while it stays consistent with the ground truth.

In other words, Fusion acts as a transparent cache + incremental build system for any computation your code runs, and as you can see, it's fast enough to be able to speed up even a code relying on in-memory EF Core provider by 1000x!

Note that:

  • Similarly to real-time updates, you get this speedup for free in terms of extra code.
  • You also get almost always consistent cache. It's still an eventually consistent cache, of course, but the inconsistency periods for cache entries are so short that normally don't need to worry about the inconsistencies.
  • The speedup you're expected to see in production may differ from these numbers a lot. Even though the results presented here are absolutely real, they are produced on a synthetic test.

"The Ungreen Web: Why our web apps are terribly inefficient?" lits more light on why this matters.

How Fusion works?

Fusion provides three key abstractions:

  • Compute Services are services exposing methods "backed" by Fusion's version of "computed observables". Compute Services are responsible for "spawning" parts of the state on-demand.
  • Replica Services - remote proxies of Compute Services. They allow remote clients to consume ("observe") the parts of server-side state. They typically "substitute" similar Compute Services on the client side.
  • And finally, IComputed<T> – an observable Computed Value that's in some ways similar to the one you can find in Knockout, MobX, or Vue.js, but very different, if you look at its fundamental properties.

IComputed<T> is:

  • Thread-safe
  • Asynchronous – any Computed Value is computed asynchronously; Fusion APIs dependent on this feature are also asynchronous.
  • Almost immutable – once created, the only change that may happen to it is transition to IsConsistent() == false state
  • GC-friendly – if you know about Pure Computed Observables from Knockout, you understand the problem. IComputed<T> solves it even better – dependent-dependency relationships are explicit there, and the reference pointing from dependency to dependent is weak, so any dependent Computed Value is available for GC unless it's referenced by something else (i.e. used).

All above make it possible to use IComputed<T> on the server side – you don't have to synchronize access to it, you can use it everywhere, including async functions, and you don't need to worry about GC.

But there is more – any Computed Value:

  • Is computed just once – when you request the same Computed Value at the same time from multiple (async) threads and it's not cached yet, just one of these threads will actually run the computation. Every other async thread will await till its completion and return the newly cached instance.
  • Updated on demand – once you have an IComputed<T>, you can ask for its consistent version at any time. If the current version is consistent, you'll get the same object, otherwise you'll get a newly computed consistent version, and every other version of it is guaranteed to be marked inconsistent. At glance, it doesn't look like a useful property, but together with immutability and "computed just once" model, it de-couples invalidations (change notifications) from updates, so ultimately, you are free to decide for how long to delay the update once you know certain state is inconsistent.
  • Supports remote replicas – any Computed Value instance can be published, which allows any other code that knows the publication endpoint and publication ID to create a replica of this IComputed<T> instance in their own process. Replica Services mentioned above rely on this feature.

Why these features are game changing?

Real-time typically implies you need one or another flavor of event-driven architecture (CQRS, event sourcing, actors, etc.). And all these options are more complex than a simple and familiar request-response model, which Fusion allows you to use.

Besides that, Fusion solves a complex problem of identifying and tracking dependencies automatically for any method that uses Fusion-based services (+ its own logic) to produce the output, and implementing this without Fusion is not only hard, but quite error prone problem.

Of course you still can use events, event sourcing, CQRS, etc. - you'll just need maybe 100× fewer event types.

Check out how Fusion differs from SignalR – this post takes a real app example (Slack-like chat) and describes what has to be done in both these cases to implement it.

Does Fusion scale?

Yes. MMORPG example provided earlier hints on how Fusion-based apps scale. But contrary to games, web apps rarely have a strong upper limit on update delay – at least for a majority of content they present. This means you can always increase these delays to throttle down the rate of outgoing invalidation and update messages, and vice versa. In other words, Fusion-based web apps should scale much better than MMORPG.

Check out "Scaling Fusion Services" part of the Tutorial to see a much more robust description of how Fusion scales.

Enough talk. Show me the code!

Compute Services is where a majority of Fusion-based code is supposed to live. CounterService from HelloBlazorServer sample is a good example of such a service:

Lime-colored parts show additions to a similar singleton service you'd probably have in case when real-time updates aren't needed:

  • [ComputeMethod] indicates that any GetCounterAsync result should be "backed" by Computed Value. This attribute works only when you register a service as Compute Service in IoC container and the method it is applied to is virtual.
  • Computed.Invalidate call finds a Computed Value "backing" the most recent GetCounterAsync call with the same arguments (no arguments in this case) and invalidates it - unless it doesn't exist or was invalidated earlier. We have to manually invalidate this value because GetCounterAsync doesn't call any other Compute Services, and thus its result doesn't have any dependencies which otherwise would auto-invalidate it.

Counter.razor is a Blazor Component that uses CounterService:

Again, lime-colored parts show additions to a similar Blazor Component without real-time updates:

  • It inherits from LiveComponentBase - a small wrapper over ComponentBase (base class for any Blazor component), which adds State property and abstract ComputeStateAsync method allowing to (re)compute the State.Value once any of its dependencies changes.
  • LiveComponent<T>.State property is a Live State - an object exposing the most current Computed Value produced by a computation (Func<...>) and making sure it gets recomputed with a controllable delay after any of its dependencies change.
  • As you might guess, ComputeStateAsync defines State.Value computation logic in any LiveComponentBase<T> descendant.

Blue-colored parts show how State is used:

  • State.LastValue is the most recent non-error value produced by the computation. It's a "safe pair" to State.Value (true most recent computation result), which throws an error if State.Error != null.
  • State.Error contains an exception thrown by ComputeStateAsync when it fails, otherwise null.

That's almost literally (minus IoC registration) all you need to have this:

And if you're curious how "X seconds ago" gets updated, notice that ComputeStateAsync invokes TimeService.GetMomentsAgoAsync, which looks as follows:

In other words, ComputeStateAsync becomes dependent on "moments ago" value, and this value self-invalidates ~ at the right moment triggering cascading ComputeStateAsync invalidation.

"Simple Chat" is a bit more complex example showing another interesting aspect of this approach:

Since any event describes a change, Fusion's only "invalidated" event ("the output of f(...) changed") allows you to implement a reaction to nearly any change without a need for a special event!

"Simple Chat" features a chat bot that listens to new chat messages and responds to them:

ChatService source code doesn't have any special logic to support chat bots - similarly to CounterService, it's almost the same as a similar service that doesn't support any kind of real-time behavior at all:

But since ChatService is a Compute Service, you can implement a "listener" reacting to changes in GetMessagesAsync output relying on e.g. Live State - and that's exactly what ChatBotService does.

Next Steps

Posts And Other Content

P.S. If you've already spent some time learning about Fusion, please help us to make it better by completing Fusion Feedback Form (1…3 min).

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].