Coder Social home page Coder Social logo

nactio / nact Goto Github PK

View Code? Open in Web Editor NEW
1.1K 27.0 54.0 1.83 MB

nact ⇒ node.js + actors ⇒ your services have never been so µ

Home Page: https://nact.xyz

License: Apache License 2.0

JavaScript 0.66% TypeScript 99.34%
actor-model nodejs actorsystem actors distributed-systems akka microservices nact

nact's People

Contributors

acefire6 avatar biancode avatar dependabot[bot] avatar elrichgro avatar fossabot avatar jaywaa avatar louwhopley avatar mcpx avatar ncthbrt avatar pelhage avatar rykilleen avatar scott-wyatt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nact's Issues

Remove Logging?

At Root, we've been using nact in production. One feature of the library we haven't really been using is logging. I would like to propose removing it in the interest of reducing the maintenance burden and increasing simplicity of code. Extension points could be opened up to allow logging to be added posthoc in a separate codebase.

Practises and Patterns

The base nact library is focusing on making a solid set of primitives.

These primitives are not enough however as users will likely find themselves implementing the same patterns over and over again.

Thus there should be another repository which abstracts and documents these patterns and makes them accessible to users of nact.

Persistence Snapshots

Given nact's design, it would make sense to create a declarative means of specifying when and how frequently snapshots of an actor state should occur. This could be part of an optional configuration parameter. An example of how this would look might be:

const { every } = require('nact');
spawnPersistent(parent, (state, msg, ctx)=> msg+state, 'key', 'name', { createSnapshot: every(6).minutes 'min')  });

setImmediate polyfill

setImmediate is used in Nact to implement non blocking macro task semantics as it is more performant for this use case than setTimeout (which in many implementations has a minimum duration). However this API is not available in most browsers. Polyfilling this API may allow Nact to work in browser

Use Cases

Hey Nick, project looks interesting! I wanted to ask what are good use cases for nact. I see that you're working on a postgres persistence plugin, I could work on a MongoDB one. I've got some time in my hands and am looking for interesting stuff to do.

Scaffolding

Starting a new nact project should be super quick and fast.

If we offer a project scaffold which adopts a convention driven approach, it'll allow devs to be more immediately productive.

AbstractPersistenceEngine.events(): Result

Current

  • AbstractPersistenceEngine.events() in here returns Result that has reduce() function.
  • But Result is only defined in here, not in nact/lib/persistence.

Problem

  • I'd had to define another Result for nact-persistence-mysql

Given,

class Result<T> {
  constructor (promise: Promise<T>) {
    this.promise = promise;
  }

  public then(...args) {
    return this.promise.then(...args);
  }

  public reduce(...args) {
    return this.promise.then(result => result.reduce(...args));
  }
}

Q. What type of parameters and return of the functions: then(), reduce() should be?

onCrash does not provide access to internal message queue

onCrash allows you to react to the message that may have caused the crash, however there may be messages in nact's internal queue for that actor which will after the crash be silently ignored.

Should allow the onCrash handler to access the mailbox in some way so that messages are not dropped, at least when on the same system.

Remove rxjs dependency

Rxjs is quite a heavy dependency and nact doesn't really need it. It is only being used in the persistence layer. The streaming API is most likely only an advantage in pathological cases where hundreds of large events have been persisted.

Bug: Persisting events after restoring fails (Postgresql Plugin)

Steps to Reproduce:

  1. Create a persistent actor
  2. Persist a few events
  3. Restart program
  4. Rehydrate actor with the same persistent key
  5. Attempt to persist a new event

This produces the following error message:

"error: duplicate key value violates unique constraint \"event_journal_uq\"
    at Connection.parseE (/Users/nick/root_bank/root-platform/service.insurance.claims/node_modules/pg/lib/connection.js:546:11)
    at Connection.parseMessage (/Users/nick/root_bank/root-platform/service.insurance.claims/node_modules/pg/lib/connection.js:371:19)
    at Socket.<anonymous> (/Users/nick/root_bank/root-platform/service.insurance.claims/node_modules/pg/lib/connection.js:114:22)
    at emitOne (events.js:115:13)
    at Socket.emit (events.js:210:7)
    at addChunk (_stream_readable.js:266:12)
    at readableAddChunk (_stream_readable.js:253:11)
    at Socket.Readable.push (_stream_readable.js:211:10)
    at TCP.onread (net.js:585:20)"

stateful actor not stopped if null or undefined returned

stateful actor not stopped if null or undefined returned
as https://nact.io/lesson/javascript/stateful-actors mentioned it should shutdown if returned null or undefined, but child continued to receive messages, passed by parent to child.

Expected Behavior

actor stopped as child

Current Behavior

actor still alive

Possible Solution

check actor state no null or undefined and stop it

Steps to Reproduce (for bugs)

const s = start();
const actor = spawn(s, (state, msg) => { console.log('received', msg); return null; }, 'actor');
dispatch(actor, 'have to exit after this');
dispatch(actor, 'no, still acting');

Context

I want to stop my actors somehow

Your Environment

  • Version used: latest
  • Environment name and version (e.g. Node v8.8): Node 9
  • Operating System and version: Mac OS

when trying to compile typescript file with nact, I receive error saying dispatch accepts only 2 arguments

Expected Behavior

When compiling a typescript file that calls dispatch from nact with 3 arguments, I should not receive this error:

actor.ts:39:34 - error TS2554: Expected 2 arguments, but got 3.
39   dispatch(ctx.sender, ctx.name, ctx.self);

Current Behavior

I receive the error when compiling:

actor.ts:39:34 - error TS2554: Expected 2 arguments, but got 3.
39   dispatch(ctx.sender, ctx.name, ctx.self);

Possible Solution

Update typing to allow for a 3rd optional argument

Steps to Reproduce (for bugs)

  1. Add the code from ping pong tutorial:
import {start,dispatch, spawnStateless} from 'nact';
const delay = (time) => new Promise((res) => setTimeout(res, time));

const ping = spawnStateless(system, async (msg, ctx) =>  {
  console.log(msg);
  // ping: Pong is a little slow. So I'm giving myself a little handicap :P
  await delay(500);
  dispatch(ctx.sender, ctx.name, ctx.self);
}, 'ping');

const pong = spawnStateless(system, (msg, ctx) =>  {
  console.log(msg);
  dispatch(ctx.sender, ctx.name, ctx.self);  
}, 'pong');

dispatch(ping, 'begin', pong);
  1. Compile with tsc

Context

I'm trying to use nact with typescript

Your Environment

  • Version used: nact 7.3.1
  • Environment name and version (e.g. Node v8.8) node 14.3.0
  • Operating System and version: macos catalina

Remove reference object identity linking

Right now nact is using a Weakmap to retrieve the reference to the actor. This is fast, but unsustainable, you cannot do remoting as this this involves copying objects.

Discord URL in README is expired

Expected Behavior

Clicking the URL should provide a valid invite

Current Behavior

The URL provides an expired invite

Possible Solution

Update URL to point to the community page, with the Discord embed

Context

Community outreach

TypeScript development environment setup

@ncthbrt

I checked out the branch refactor-typescript, on which you did some refactoring.

I found you changed many things in nact-core, but the others that depend on nact-core haven't been changed properly according to it.

Now it is failing to compile.

I wonder whether you used tsc compiler on your works.

If needed, I want to share with you something about TypeScript development environment and how to run tsc compiler.

And what kind of IDE do you use on development?

I'm using VSCode with some TS extensions, such as TSLint, TS Prettier.

It's good to use some kind of linter and code prettier (formatter).

Thank you.

Http Actors

First step to getting clustering working is to allow actors to communicate with one another via tcp/udp/http/some form of communication channel.

Could it be that `spawnPersistent` never returns if passed the same name twice?

Expected Behavior

I guess I'd expect spawnPersistent to either throw an error or return the existing child with the same name, rather than just not return.

Current Behavior

I was having a problem with not being able to query an actor twice: the first query succeeded, but then further queries timed out. I ended up tracking the problem down to spawnPersistent not returning when the same name was passed to it a second time.

Steps to Reproduce (for bugs)

  1. Setup the system and actors like in https://nact.io/lesson/javascript/hierarchy
  2. Mistakenly pass a fixed name to the spawn function, e.g. instead of childActor = spawnUserContactService(ctx.self, userId) do something like childActor = spawnUserContactService(ctx.self, "userId")

The Hierarchy documentation uses spawn, but I used spawnPersistent - I'm guess that's probably not important in this context.

Your Environment

  • Version used: 7.0.1 (and nact-persistence-postgres v7.0.0)
  • Environment name and version: node 9.6
  • Operating System and version: OS X 10.10.5

Typescript ActorRefs are unsoundly typed.

I've started a branch /refactor-typescript to address these issues.

Problems present on current dev branch are as follows:

  1. Sender - The sender property makes sound typing impossible as it either couples the senders and recipients too tightly together or it removes the type information. Sender is to be removed in a soundly typed implemention. c.f. reason-nact
  2. Children - The Children Ref of a given actor are currently typed ActorRef<any> they should be instead changed to ActorRef<unknown> to indicate that by default we do not know what messages a child can handle in advance. In general any any should be removed from the public facing api.
  3. Context, SupervisionContext, Actor all need to include the message type of the parent as well as the current actor. This IS known by a child actor in advance and allows a child actor to freely message a parent without casting.
  4. Serialized messages and decoders/encoders - Messages coming back from the database cannot be soundly typed as this is out of nact's control. Persistent actors should be typed as Json by default unless they include a encoder/decoder tuple which maps Json to an actual type.

Unrelated to soundness, but still important:

  1. References - Currently references include get methods and extraneous fields. These fields and methods need to be removed as references must be serializable to json without information loss.
  2. Separation of implementation details from public API - Nact is kind of like an iceburg. There is a lot of implementation details that users don't need to directly interact with unless they wish to extend the framework. It would be nice to make it clearer in source which files are part of the public API and which are not. Currently I removed implementation details to a folder called internals (for want of a better name)

dispatch has wrong type signature

dispatch has type signature function dispatch<T>(actor: Ref<T>, msg: T): void; but the example at https://nact.io/en_uk/lesson/javascript/actor-communication demonstrates passing it a 3rd argument.

Expected Behavior

It should document itself correctly.

Current Behavior

It is missing documentation about the third param.

Steps to Reproduce (for bugs)

  1. Follow the getting started guide
  2. When you get to the Communication step in vscode have a look at the tooltip it shows for dispatch.

Context

It's not a great experience to have the docs at your fingertips be incorrect.

Your Environment

  • Version used: ^7.3.0
  • Environment: vscode 1.46.0

multicore cup

Is nact ability to take full advantage of multicore cup resources ?
or all atcors run only on a single cup?

Make Actor References Observable

Stateful actors use the "reducer" abstraction to deal with state management (but allow side effects inside the reducer too). It would be a natural addition to allow subscription to state changes (much like redux, but potentially remotely) and if subscriptions are supported, it would be natural to provide this using RXJS as it is highly composable, and a rxjs-like abstraction has been well proven in Akka with Akka streams.

Benchmarks

Performance has thus far been a secondary concern to features. As nact evolves and matures however, it will become important to ensure that we have a robust suite of benchmarks so as to evaluate whether performance is improving or regressing.

Core Concepts: Command/Event Sourcing; Write/Read Side

I just left this for future consideration.

Example: Protocol Design

I used pseudo-code here for succinct notation.

interface Event
class ContactCreated(contact: Contact) : Event
class EmailModified(email: string) : Event

interface Command
class CreateContact(form: ContactForm) : Command
class ModifyEmail(contactId: ContactId, email: string) : Command

interface ReadOnlyCommand
class GetContact(contactId: ContactId) extends ReadOnlyCommand
class GetContacts : ReadOnlyCommand

type MSG = Event | Command | ReadOnlyCommand

Example: Message Handler

These are written in TypeScript.

  • ContactManagerActor
async function handle(state: ST, msg: MSG, ctx: Context): Promise<ST> {
  switch (msg.$type) {
    // Command
    case 'CreateContact': {
      const contact = // create new contact
      const event = new ContactCreated(contact)
      await ctx.persist(event)
      return this.handle(state, event, ctx)
    }
    case 'ModifyEmail': {
      const contactId = msg.contactId
      const contactActor = ctx.children.get(contactId) || spawnPersistent(ctx.self, ContactActor.handle, {{ persistenceKey }}, {{ name }})
      dispatch(contactActor, msg, ctx.sender)
      return state
    }
    
    // Event
    case 'ContactCreated': {
      const contactId = msg.contact.contactId
      const contactActor = ctx.children.get(contactId)
      if (contactActor) {
        throw new Error('exception!')
      } else {
         spawnPersistent(ctx.self, ContactActor.handle, {{ persistenceKey }}, {{ name }}, {
           initialState: {
             contactId,
             contact: msg.contact
           }
         )
      }
      return {
         ...state,
         contactIds: [...state.contactIds, contactId]
      }
    }
    
    // ReadOnlyCommand
    case 'GetContact': {
       const contactId = msg.contactId
       const contactActor = ctx.children.get(contactId) || spawnPersistent(ctx.self, ContactActor.handle, {{ persistenceKey }}, {{ name }})
       dispatch(contactActor, msg, ctx.sender)
       return state
    }
    
    case 'GetContacts': {
      // this command doesn't fit well.
      // kind of `findAll` command should use `read side` model instead of spawning all actors and retrieving data from them.
    }
    
    default:
      return state
  }
} 

interface ST {
  contactIds: ContactId[]
}
  • ContactActor
async function handle(state: ST, msg: MSG, ctx: Context): Promise<ST> {
  switch (msg.$type) {
    // Command
    case 'ModifyEmail': {
      const event = new EmailModified(msg.email)
      await ctx.persist(event)
      return this.handle(state, event, ctx)
    }
    
    // Event
    case 'EmailModified': {
      const nextState = lens<ST>().contact.email.set(msg.email)(state)
      return nextState
    }
    
    // ReadOnlyCommand
    case 'GetContact': {
      dispatch(ctx.sender, state.contact)
      return state
    }
    case 'GetContacts': {
       dispatch(ctx.sender, state.contact)
       return state
    }

    default:
      return state
  }
} 

interface ST {
  contactId: ContactId,
  contact: Contact
}

Questions

  • Command Sourcing vs. Event Sourcing?
    • As far as I know, in the tutorial, it describes nact uses command sourcing.
  • Distinguished Message Roles: Command / Event / ReadOnlyCommand
    • can avoid if (!ctx.recovering) { ... }
    • message naming convention
      • Command: DoXXX (imperative)
      • Event: XXXed (past tense)
      • ReadOnlyCommand: 'GetXXX' (getter, query)
  • Write/Read Side
    • kind of GetAllXXX command doesn't fit what nact provides.
  • ...

Perhaps having two ways of dispatching messages is confusing.

Both the context object and actor references have a dispatch() method. The input arguments differ between them. This has lead to confusion (based on feedback).

It perhaps might be worthwhile to refactor the context object to not include the dispatch method. This has the downside of having to explicitly include the sender. On the upside it means a single way of sending a message to other actors and a more consistent api

Nact in browser

It'd be an interesting development to get nact working in the browser. There is no fundamental reason right now why it wouldn't be possible. This would enable a few things:

  • It could take the place of redux.
  • Allow very clean client-server communication via websockets/http2/etc

Supervision

Currently stateful actors just shutdown after a crash. We require a way to define policies on parents to deal with crashes in a sane manner. This is a fundamentally important part of actor systems

Death Watch

State watch would probably be a more idiomatic way of doing things than using rxjs.
It also would fit into the reason wrapper better.

Compulsory timeout argument to query

query is a somewhat dangerous operation. It can cause a system to lock up if the timeout defaults to what is for most intents and purposes is an infinite duration. The solution is to throw if a timeout is not provided, as this will prevent errors and unexpected behaviour.

Rewrite in TypeScript

Expected Behavior

Type definitions for TypeScript (index.d.ts) should be provided.

Current Behavior

There is no type definition provided, either in nact or @types/nact.

Possible Solution

https://github.com/civilizeddev/nact/blob/master/lib/index.d.ts
I wrote this above, using it in my own project. I just want to share it.

if you contributors are pleased I think it would be better to rewrite the whole project in TypeScript.

Context

I am also Java and Scala developer, but currently working with TypeScript in Node. I was pleased that there is akka-like actor implementation even in JavaScript. Thank you.

Your Environment

  • nact 7.2.1
  • Node 8.15.0 LTS
  • TypeScript 3.3.3

Clustering

One of the major benefits of actor systems is location transparency; being able to communicate with remote actors in the same way as local actors is an important feature of this

This feature could be as basic as having some means to allow actors to communicate when IP addresses are explicitly provided, or it could also include scheduling (deciding where actors should be put) and clustering.

Another important question is how to ensure that this architecture is flexible enough to support different kinds of transports, while selecting some sane, easy to setup defaults.

ActorContext type doesn't have ctx.sender property

ActorContext type doesn't have ctx.sender property.
https://github.com/ncthbrt/nact/blob/b28048869c745b305c253d1b22c18c39ba26f122/lib/index.d.ts#L63-L70

but in official docs, when perform response of query, ctx.sender is needed.
https://nact.io/en_uk/lesson/javascript/querying

so I did like this(workaround)

// request
await query(actorX, (_: ActorX) => "Let there be light", 5000)

// response(In actorX's msg handler)
dispatch((ctx as any).sender, "and there was light")

Expected Behavior

Current Behavior

Possible Solution

Steps to Reproduce (for bugs)

Context

Your Environment

  • Version used: 7.1.3
  • Environment name and version (e.g. Node v8.8): Node v10.18.1
  • Server type and version: Ubuntu 20.04
  • Operating System and version: Ubuntu 20.04
  • Link to your project:

Actors in the same system do not run in parallel

Code like:

const {start, spawnStateless, dispatch} = require('nact');

// create actor system
const system = start();

// a complex calculation model
function intensive_computation() {
    let intensity = 100000000;
    while (intensity > 0) {
        // intensity--;
    }
}

// create an actor(actorA)
let actorA = spawnStateless(system,
    function (msg, ctx) {
        console.log("i am %s, msg: %s", this.name, msg.word);
        console.time(this.name);
        intensive_computation();
        console.timeEnd(this.name);
    },
    "compute-intensive-actor"
);

// create an actor(actorB)
let actorB = spawnStateless(system,
    function (msg, ctx) {
        console.log("i am %s, msg: %s", this.name, msg.word);
    },
    "other-actor"
);

// start actor A
dispatch(actorA, {
    word: 'start computing...'
});

// start actor B
dispatch(actorB, {
    word: 'i need some cpu resource...'
});

Issue description

actorB will never be executed before actorA finished. the time-consuming actor will blocks all the other actors.
so... actors in the same system do not run in parallel??

Environment

  • Operating System: windows 10
  • Nact version: v7.2.2
  • Nodejs version: v10.15.3

Actor Idle Timeout

Once spawned, actors take up memory even if they're not handling messages. Shutting actors down frees this resource.

Given nact's design, it would make sense to create a declarative means of specifying when an actor should automatically shutdown due to inactivity. The interface for this could look something like the following:

const { after } = require('nact');
spawn(parent, (state, msg, ctx)=> msg+state, 'name', { shutdown: after(6, 'min').ofInactivity  });

spawnStateless ignores onCrash property

Passing an onCrash property when using spawnStateless() has no effect: The actor always resumes.

Expected Behavior

The onCrash property should be honoured when calling spawnStateless().

Current Behavior

When calling spawnStateless(), the onCrash property is ignored.

This implies that the supervision example in the documentation won't work.

Possible Solution

When initialising the properties here, putting the spread of properties last would fix it, if the intention is to have a (overridable) default:

    { onCrash: (_, __, ctx) => ctx.resume, ...properties }

Steps to Reproduce (for bugs)

The supervision example in the documentation won't work, it will always resume (instead of reset, as documented).

Context

I've just started learning about this package, so I might be missing something.

Your Environment

  • Version used: 7.2.1
  • Environment name and version: Node 11
  • Operating System and version: OSX, Debian

More example code

A number have people have requested example code to better illustrate nact's use cases. I think it's a good idea.

Proposal for sample code:

  • A basic multiuser chat server with persistence
  • Some browser based multiplayer game?

Suggestion - use generator yield for dispatching messages

This framework looks extremely interesting.

I was wondering, have you considered following a "redux-saga" like model for dispatching messages between actors? e.g.:

const pingBehavior = async (msg, ctx) =>  {
  console.log(msg);
  await delay(500);
  yield dispatch(ctx.sender, ctx.name, ctx.self); // <--- here's where this differs from the docs example.
};

const ping = spawnStateless(system, pingBehavior, 'ping');

Where dispatch() would just produce an object which is used by the framework to do the actual sending:

const dispatch = (actor, msg, sender) => ({ DISPATCH: { actor, msg, sender }});

This would make actor "behaviour" functions potentially side-effect free, which would have testability benefits.

Typescript: Unable to call three arguments in dispatch function

@ncthbrt
Managed to install nact and used it in a typescript project.
However, i did not manage to run the ping pong example.

Expected Behavior

  1. I should able to call the dispatch function in nact/lib/functions.js with three arguments.
  2. The ctx from the callback function in spawnStateless should able to have sender property.

Current Behavior

import nact from "nact";
const system = nact.start();
const delay = (time) => new Promise((res) => setTimeout(res, time));

const ping = nact.spawnStateless(system, async (msg, ctx) =>  {
  console.log(msg);
  await delay(500);
  
  // ERROR:
  // 1. Error message regarding ctx.sender
  // Property 'sender' does not exist on type 'ActorContext<any, ActorSystemRef>'.
  // 2. Error message regarding nact.dispatch
  // (property) self: nact.Ref<any>
  // Expected 2 arguments, but got 3.ts(2554)
  nact.dispatch(ctx.sender, ctx.name, ctx.self);
}, 'ping');

Steps to Reproduce

  1. Install nact version ~7.2.2
  2. Run examples/ping-pong/ping-pong-stateless.js in typescript fashion

Context

  1. I am trying to use nact in a typescript project.
  2. I have found also that in refactor-typescript branch: https://github.com/ncthbrt/nact/blob/refactor-typescript/nact-core/src/functions.ts, the dispatch function accepts only two arguments.

Your Environment

  • Version used: nact version 7.2.2
  • Typescript version: 3.7.5

Are there any steps that I should be aware when using typescript in nact?
Thanks for the help.

Principle of Use

Principle of Use

What kind of Principle of Use would be there when using nact? Add here.

1. Don't use class to define Command, Event, State

Bad

class GetContact {
  constructor(contactId) {
    this.contactId = contactId
  }
}

const command = new GetContact(1234)

Good

const command = {
  contactId: 1234
}

Good (for TypeScript)

interface is recommended instead of class

interface GetContact {
  contactId: number
}

const command: GetContact = {
  contactId: 1234
}

Why?

  • Different than Java or C#, In JavaScript arbitrarily object created by {} is mostly used.
  • Many of JavaScript library still work on arbitrarily objects only.
  • In nact, messages and states are to be serialized and deserialized. Using class instances might have problem because they would lose constructor (and prototype chain) information during the process.
  • While there is kind of typescript-json-serializer, it would make your code base more verbose and introduce additional complexity. (I realized.)

Snapshotting has one-state lag, leading to "Failed to take snapshot Error: data should not be null or undefined"

Expected Behavior

The snapshot is taken on the state after the first message, rather than on the null state.

Current Behavior

With snapshotEvery: 1 * messages, I noticed that the snapshot is always one state behind.

This also leads to the error "Failed to take snapshot Error: data should not be null or undefined" when nact tries to persists the first time.

Steps to Reproduce (for bugs)

  1. Spawn a persistant actor with the option {snapshotEvery: 1 * messages}
  2. Process a message to create the state object

Context

It'd be nice if the snapshot took place after the message is processed rather than before (if that's indeed what's happening). This would ensure that the snapshot is really up-to-date and avoid re-processing the last message every time the actor is restarted.

Your Environment

  • Version used: 6.1.0 (and nact-persistence-postgres v6.0.2)
  • Environment name and version (e.g. Node v8.8): node 9.6
  • Operating System and version: OS X 10.10.5

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.