Git Product home page Git Product logo

feathers-sync's Introduction

Feathers sync

CI Download Status

Synchronize service events between application instances

About

When running multiple instances of your Feathers application (e.g. on several Heroku Dynos), service events (created, updated, patched, removed and any custom defined events) do not get propagated to other instances.

feathers-sync uses a messaging mechanism to propagate all events to all application instances. It currently supports:

This allows to scale real-time websocket connections to any number of clients.

Usage

The application initialized in the following example will use the local feathers-sync database and sync collection and share service events with every other instance connected to the same database:

const feathers = require('@feathers/feathers');
const sync = require('feathers-sync');

const app = feathers();

app.configure(
  sync({
    uri: 'redis://localhost:6379',
  })
);
app.use('/todos', todoService);

Note that configuring sync should happen before configuring services

app.sync

When set up, app.sync will contain the following information:

  • type - The adapter type (e.g. redis or amqp)
  • ready - A promise that resolves when the synchronization mechanism is ready
app.sync.ready.then(() => {
  // Do things here
});

Disabling synchronization

feathers-sync can be disabled on the service method call level in a hook by setting the require('feathers-sync').SYNC property on the hook context to false:

const { SYNC } = require('feathers-sync');

app.service('messages').hooks({
  after: {
    create(context) {
      // Don't synchronize if more than 1000 items were created at once
      if (context.result.length > 1000) {
        context[SYNC] = false;
      }

      return context;
    },
  },
});

Adapters

feathers-sync can be initialized either by specifying the type of adapter through the uri (e.g. redis://localhost:6379) or using e.g. sync.redis directly:

// Configure Redis
app.configure(
  sync({
    uri: 'redis://localhost:6379',
  })
);

app.configure(
  sync.redis({
    db: redisInstance,
  })
);

// Configure Redis using an existing redisClient
app.configure(
  sync.redis({
    redisClient: redisClient,
  })
);

Redis

  • uri - The connection string (must start with redis://)
  • key - The key under which all synchronization events will be stored (default: feathers-sync)
  • redisClient - An existing instance of redisClient
  • redisOptions - Redis client options

AMQP

  • uri - The AMQP connection string (e.g. amqp://guest:guest@localhost:5672).
  • key (default: feathers-sync) - The name exchange where sync messages will be published
  • amqpConnectionOptions - AMQP connection options

NATS

  • uri - The connection string (example nats://)
  • key (default: feathers-sync) - The name of subject where sync messages will be published
  • natsConnectionOptions - NATS connection options

How it works

alt tag

Caveat: Listening to service events

With feathers-sync enabled all events are going to get propagated to every application instance. This means, that any event listeners registered on the server should not perform any actions that change the global state (e.g. write something into the database or call to an external API) because it will end up running multiple times (once on each instance). Instead, event listeners should only be used to update the local state (e.g. a local cache) and send real-time updates to all its clients.

If you need to perform actions, for example setting up a first blog post after a new user has been created, add it to the service method itself or use a Feathers hook (both of which will only run once on the instance that is handling the request).

Custom Serializer / Deserializer

Event data are serialized and deserialized using JSON.stringify and JSON.parse. This could pose a problem if the event data contains circular reference or has Date values (Date is not a valid JSON value (source) and will be serialized to a string). You can provide a custom serializer/deserializer like this:

// BSON can serialize / deserialize `Date` values.
const bson = require('bson');

app.configure(
  sync({
    uri: 'redis://localhost:6379',
    // Replies will be sent to callbacks as Buffers instead of Strings for bson.deserialize to work.
    redisOptions: { return_buffers: true },
    serialize: bson.serialize,
    deserialize: bson.deserialize,
  })
);

Redis and AMQP can support binary serialization / deserialization (i.e. Buffer data). NATS currently does not support custom serialization / deserialization/

Writing custom adapters

feathers-sync allows to implement custom adapters using the sync-in and sync-out events on the application:

const { core } = require('feathers-sync');
const myMessagingService = {
  publish(data) {
    // send data here
  },

  subscribe(callback) {
    // subscribe to message queue and emit data
  },
};

module.exports = (config) => {
  // If adapter supports configurable serializer / deserializer (defaults to `JSON.stringfy` / `JSON.parse`)
  const { deserialize, serialize } = config;

  return (app) => {
    app.configure(core);
    app.sync = {
      type: 'custom',
      ready: new Promise((resolve, reject) => {
        // resolve when client is ready
        // reject on connection error
      }),
      serialize,
      deserialize,
    };

    // Sent every time a service
    app.on('sync-out', (data) => {
      // Publish `data` to the message queue
      myMessagingService.publish(data);
    });

    myMessagingService.subscribe((data) => {
      // Send the synchronization event to the application
      app.emit('sync-in', data);
    });
  };
};

The data for the sync-in event should be in the same form as the one that is sent by sync-out (currently it includes { event, path, data, context }).

License

Copyright (c) 2021 Feathers contributors

Licensed under the MIT license.

feathers-sync's People

Contributors

babysealclubber avatar corymsmith avatar daffl avatar deskoh avatar dubiousdavid avatar ekryski avatar fbarzin avatar fragilehm avatar green3g avatar greenkeeper[bot] avatar greenkeeperio-bot avatar kc-dot-io avatar mrfrase3 avatar palmtown avatar pedromd avatar superlazycoder avatar thebarndog avatar thegc avatar thomaschaaf avatar tinque avatar viljarvoidula 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

feathers-sync's Issues

mubsub dependency is using too old mongodb driver

We are using feathers with mongodb driver (version: 3.1.10) but mubsub is using mongodb with version 2.0.35. When we try to run feathers-sync in our API Gateway implementation we get the following exception:

TypeError: collection.find(...).sort(...).limit(...).nextObject is not a function

An ideas how to solve this problem and make feathers-sync usable with mongodb version 3.x?

An in-range update of mocha is breaking the build 🚨

Version 3.3.0 of mocha just got published.

Branch Build failing 🚨
Dependency mocha
Current Version 3.2.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As mocha is β€œonly” a devDependency of this project it might not break production or downstream projects, but β€œonly” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this πŸ’ͺ

Status Details - ❌ **continuous-integration/travis-ci/push** The Travis CI build failed [Details](https://travis-ci.org/feathersjs/feathers-sync/builds/225206310)

Release Notes coverave

Thanks to all our contributors, maintainers, sponsors, and users! ❀️

As highlights:

  • We've got coverage now!
  • Testing is looking less flaky \o/.
  • No more nitpicking about "mocha.js" build on PRs.

πŸŽ‰ Enhancements

  • #2659: Adds support for loading reporter from an absolute or relative path (@sul4bh)
  • #2769: Support --inspect-brk on command-line (@igwejk)

πŸ› Fixes

  • #2662: Replace unicode chars w/ hex codes in HTML reporter (@rotemdan)

πŸ” Coverage

πŸ”© Other

Commits

The new version differs by 89 commits0.

  • fb1687e :ship: Release v3.3.0
  • 1943e02 Add Changelog for v3.3.0
  • 861e968 Refactor literal play-icon hex code to a var
  • 1d3c5bc Fix typo in karma.conf.js
  • 9bd9389 Fix spec paths in test HTML files
  • 0a93024 Adds tests for loading reporters w/ relative/absolute paths (#2773)
  • 73929ad Comment special treatment of '+' in URL query parsing
  • e2c9514 Merge pull request #2769 from igwejk/support_inspect_break_in_opts
  • 038c636 Support --inspect-brk on command-line
  • b4ebabd Merge pull request #2727 from lamby/reproducible-build
  • 882347b Please make the build reproducible.
  • a2fc76c Merge pull request #2703 from seppevs/cover_utils_some_fn_with_tests
  • ed61cd0 cover .some() function in utils.js with tests
  • f42cbf4 Merge pull request #2701 from craigtaub/landingSpec
  • 6065242 use stubbed symbol

There are 89 commits in total.

See the full diff

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

Disabling synchronization on authentication doesn't work

I've all of a sudden started getting an error of app.emit is not a function when users try to log in. I've not be able to work out exactly why but figured it was something to do with feathers-sync. So I've tried to disable it in my authentication hooks but it has no effect.

app.service('authentication').hooks({
    before: {
      create: [
        lowerCase('email'),
        authentication.hooks.authenticate(config.strategies),
        customizeJWTPayload()
      ]
    },
    after: {
      create: [
        context => {
          context[SYNC] = false;
          return context;
        }
      ]
    }
  });

What about a feathers-Β΅service instead

Starting working on a FearthersJS-based micro-service architecture I wonder if this module could not be a little bit extended to cover this use case. Indeed it actually already covers two main features IMHO:

  • connect (or plan to connect) FeathersJS with different "message bus" technologies (AMQP, Kafka, etc.)
  • perform real-time dispatch of any service event on the bus
    It would be pity to develop again this in another module dedicated to micro-services.

So my proposal is to extend this module:

  • add a small service proxy class that simply proxy requests/responses to a remote service using feathers-client (or the message bus ?)
  • add an event in the Feathers app when a new service is created so this event would be propagated on the bus
  • each node receiving this event will create a service proxy to the remote service so that any incoming request for the remote service will be dispatched to it

Let me know what you think and If you prefer to keep this module focused. In this case I would do something on my own. Thanks.

Add support for DynamoDB (AmazonAWS)

The possibility of adding support for amazon's DynamoDB? Since applications deployed there, if you do not use their own NOSQL Storage service, you must upload a new EC2 instance with MongoDB

Little question i am Missing Something?

This only shares events right? so the same events that i get when i connect with a client to each instance and listen on it?

I am just wondering because i want to code a remote socket based api for a fingerprint reader and feathers looks like it will not fit ??? i need to send commands and get callbacks from diffrent fingerprinters on diffrent devices.

ideal would be all the fingerprinters and clients connect to a single server and using the fingerprint service like emit cmd ... callback but i don't get how to do that

An in-range update of amqplib is breaking the build 🚨

The dependency amqplib was updated from 0.5.2 to 0.5.3.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

amqplib is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.

Status Details
  • ❌ continuous-integration/travis-ci/push: The Travis CI build could not complete due to an error (Details).

Commits

The new version differs by 38 commits.

There are 38 commits in total.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Node Crashes on user service `patch` or `put` requests

Steps to reproduce

Make a put or patch request to the users collection. Even without any hooks running. This could be a problem with feathers-authenticate.

Problem: Node crashed with this error

/Users/myuser/Desktop/POCS/Feathers-Vue/node_modules/mongodb/lib/utils.js:123
process.nextTick(function() { throw err; });
^

TypeError: Cannot read property 'app' of undefined
at Object.updateEntity (/Users/myuser/Desktop/POCS/Feathers-Vue/node_modules/feathers-authentication/lib/socket/update-entity.js:4:17)
at emitOne (events.js:101:20)
at Object.emit [as _emit] (events.js:189:7)
at Channel. (/Users/myuser/Desktop/POCS/Feathers-Vue/node_modules/feathers-sync/src/mongodb.js:23:27)
at emitOne (events.js:96:13)
at Channel.emit (events.js:189:7)
at Channel. (/Users/myuser/Desktop/POCS/Feathers-Vue/node_modules/mubsub/lib/channel.js:169:22)
at /Users/myuser/Desktop/POCS/Feathers-Vue/node_modules/mubsub/lib/channel.js:245:18
at handleCallback (/Users/myuser/Desktop/POCS/Feathers-Vue/node_modules/mongodb/lib/utils.js:120:56)
at /Users/myuser/Desktop/POCS/Feathers-Vue/node_modules/mongodb/lib/cursor.js:682:5
at handleCallback (/Users/myuser/Desktop/POCS/Feathers-Vue/node_modules/mongodb-core/lib/cursor.js:171:5)
at nextFunction (/Users/myuser/Desktop/POCS/Feathers-Vue/node_modules/mongodb-core/lib/cursor.js:682:5)
at /Users/myuser/Desktop/POCS/Feathers-Vue/node_modules/mongodb-core/lib/cursor.js:640:9
at queryCallback (/Users/myuser/Desktop/POCS/Feathers-Vue/node_modules/mongodb-core/lib/wireprotocol/3_2_support.js:210:5)
at /Users/myuser/Desktop/POCS/Feathers-Vue/node_modules/mongodb-core/lib/connection/pool.js:461:18
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)

System configuration

Mac
Node: v7.6.0
"feathers-authentication": "^1.2.4"
"feathers-sync": "^0.1.3"

receive events in an app from another app

Using feather-sync, Is it possible to receive events in an app (instead of a client) from another app. Or only clients can listen to events from apps.

Tried the below which doesn't work (remember seeing something similar somewhere but not able to find now) ,

App1 has Uploads service

app.use('uploads',...)
...
app.create(...

App2, Event receiving app

    app.on('uploads/created', (data) => {
        logger.info('data', data);
    })

Use case: When a service created event happens in App1, then app2, (app3 ...) needs to run a local service created call.

An in-range update of @feathersjs/feathers is breaking the build 🚨

The devDependency @feathersjs/feathers was updated from 3.2.1 to 3.2.2.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

@feathersjs/feathers is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ❌ continuous-integration/travis-ci/push: The Travis CI build failed (Details).

Commits

The new version differs by 13 commits.

  • da6e273 chore(release): publish %s
  • 136b166 chore: Update debug in group default to the latest version πŸš€ (#989)
  • 5b3b37e fix: Support Logger swallowing (#995)
  • a13929c chore: Re-enable tests for generators in CI (#1008)
  • 1380bb3 Greenkeeper/lerna 3.4.0 (#1007)
  • c2fe22f Add additional ignores
  • 72132d1 fix: Update 404.html (#984)
  • cec6bae fix: Update 401.html (#983)
  • 3aa7c33 Update default.html (#985)
  • 1cc39ee Update Lerna settings
  • 5ebb789 chore: Ignore additional changes for Lerna
  • 3ca7e97 fix: use minimal RegExp matching for better performance (#977)
  • b5048e2 chore: Update changelogs to allow automatic generation with conventional commits (#975)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Mongo events don't get emitted on serverX

Expected behavior

Server2 should emit the event that server1 sends.

Actual behavior

server1:

  feathers-sync subscribing to handler locations created +0ms
  feathers-sync subscribing to handler locations updated +0ms
  feathers-sync subscribing to handler locations removed +0ms
  feathers-sync subscribing to handler locations patched +0ms
Feathers application started on 127.0.0.1:3031
  feathers-sync emitting event to channel auth/token created +4s
  feathers-sync emitting event to channel auth/token created +13ms
  feathers-sync got event, calling old emit auth/token created +81ms
  feathers-sync got event, calling old emit auth/token created +4ms

  feathers-sync emitting event to channel locations created +22s

server2:

  feathers-sync subscribing to handler locations created +0ms
  feathers-sync subscribing to handler locations updated +0ms
  feathers-sync subscribing to handler locations removed +0ms
  feathers-sync subscribing to handler locations patched +0ms
Feathers application started on 127.0.0.1:3032


There is also no event in the mongo events collection:

db.events.find({event: "locations created"}).sort({_id:-1}).limit(5)

Returns nothing, however there are some auth/* events.

System configuration

Tell us about the applicable parts of your setup.

Module versions (especially the part that's not working):
"body-parser": "^1.15.0",
"compression": "^1.6.1",
"cors": "^2.7.1",
"crypto": "0.0.3",
"elasticsearch": "^11.0.1",
"feathers": "^2.0.0",
"feathers-authentication": "^0.7.9",
"feathers-configuration": "^0.2.2",
"feathers-errors": "^2.1.0",
"feathers-hooks": "^1.6.1",
"feathers-hooks-common": "^2.0.1",
"feathers-mongoose": "^3.6.1",
"feathers-rest": "^1.2.5",
"feathers-sequelize": "^1.3.3",
"feathers-socketio": "^1.3.4",
"feathers-sync": "^0.1.1",
"hashids": "^1.1.1",
"lodash": "^4.16.2",
"mailgun-js": "^0.7.13",
"mongoose": "^4.6.6",
"mongoose-history": "^0.4.2",
"newrelic": "^1.34.0",
"passport": "^0.3.2",
"passport-local": "^1.0.0",
"pg": "^4.5.6",
"pg-hstore": "^2.3.2",
"pg-pool": "^1.5.0",
"randomstring": "^1.1.5",
"raven": "^0.12.1",
"request": "^2.75.0",
"request-promise": "^4.1.1",
"sequelize": "^3.21.0",
"serve-favicon": "^2.3.0",
"shortid": "^2.2.6",
"winston": "^2.2.0"

NodeJS version:
4.6.2

Operating System:
Ubuntu16.04

Browser Version:

React Native Version:

Module Loader:

An in-range update of feathers is breaking the build 🚨

Version 2.1.5 of feathers just got published.

Branch Build failing 🚨
Dependency feathers
Current Version 2.1.4
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As feathers is β€œonly” a devDependency of this project it might not break production or downstream projects, but β€œonly” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this πŸ’ͺ

Status Details
  • ❌ continuous-integration/travis-ci/push The Travis CI build failed Details

Commits

The new version differs by 5 commits.

See the full diff

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

Hook is not being emitted

Hello everybody,

Been testing this and everything was fine until i noticed my hook was always undefined when adding filters to my events. I've forked it and hook is now being emitted as well, but I'm not sure this is the right approach: PedroMD@ce23831

I haven't submitted a PR yet, because it is causing issues with socket.io, whenever a client connects to it:

RangeError: Maximum call stack size exceeded at _hasBinary (/home/ubuntu/apps/x-api/node_modules/socket.io/node_modules/has-binary/index.js:25:22) at _hasBinary (/home/ubuntu/apps/x-api/node_modules/socket.io/node_modules/has-binary/index.js:49:63) at _hasBinary (/home/ubuntu/apps/x-api/node_modules/socket.io/node_modules/has-binary/index.js:49:63)

EDIT: Looks like hook can't be passed alongside the data, as the hook obj has some circular references, resulting in recursive calls that exceeded the stack size: socketio/socket.io#1665

Any thoughts on how to solve this? For now, I'm thinking of switching to primus and just use engine.io as the framework (I need polling-failover on my project, as having websocket as the only transport protocol is not an option). Not sure if engine.io will do the trick, but we'll see...

Mubsub: broken cursor

I have 2 apps both using feathers-sync, both on the same servers and both connecting the same mongo replica set although using seperate databases. But on one of the app I keep getting this error.

I'm posting in here as feathers-sync is the only package I have installed that uses mubsub which hasn't been updated in a while and doesn't look like any of the issues are being answered.

error: uncaughtException: Mubsub: broken cursor.
Error: Mubsub: broken cursor.
    at Timeout._onTimeout (/app/node_modules/mubsub/lib/channel.js:159:40)
    at ontimeout (timers.js:498:11)
    at tryOnTimeout (timers.js:323:5)
    at Timer.listOnTimeout (timers.js:290:5) {"error":{},"stack":"Error: Mubsub: broken cursor.\n    at Timeout._onTimeout (/app/node_modules/mubsub/lib/channel.js:159:40)\n    at ontimeout (timers.js:498:11)\n    at tryOnTimeout (timers.js:323:5)\n    at Timer.listOnTimeout (timers.js:290:5)","exception":true,"date":"Tue Sep 25 2018 13:33:34 GMT+0000 (UTC)","process":{"pid":37,"uid":5000,"gid":5000,"cwd":"/app","execPath":"/app/.heroku/node/bin/node","version":"v8.12.0","argv":["/app/.heroku/node/bin/node","/app/src"],"memoryUsage":{"rss":254562304,"heapTotal":158777344,"heapUsed":122627880,"external":96841016}},"os":{"loadavg":[0.158203125,0.12060546875,0.13720703125],"uptime":14526604},"trace":[{"column":40,"file":"/app/node_modules/mubsub/lib/channel.js","function":"Timeout._onTimeout","line":159,"method":"_onTimeout","native":false},{"column":11,"file":"timers.js","function":"ontimeout","line":498,"method":null,"native":false},{"column":5,"file":"timers.js","function":"tryOnTimeout","line":323,"method":null,"native":false},{"column":5,"file":"timers.js","function":"Timer.listOnTimeout","line":290,"method":"listOnTimeout","native":false}]}

Error: Cannot find module 'feathers-sync'

I'm puzzled here... I installed feathers-sync and it's present in package.json as well as in my node_modules folder. But when I require it in my code, I am still getting Error: Cannot find module 'feathers-sync'... I have tried reinstalling it many times and that didn't solve the problem. The entry in my package.json says "feathers-sync": "^0.1.0".

An in-range update of @feathersjs/feathers is breaking the build 🚨

The devDependency @feathersjs/feathers was updated from 3.3.0 to 3.3.1.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

@feathersjs/feathers is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ❌ continuous-integration/travis-ci/push: The Travis CI build failed (Details).

Commits

The new version differs by 15 commits.

  • 8c3a740 Publish
  • ed8c2e4 fix: Do not inherit app object from Object prototype (#1153)
  • 8e129d8 fix(chore): Add .npmignore to adapter-commons
  • fa30617 Publish
  • c9f55d8 fix(adapter-commons): Keep Symbols when filtering a query (#1141)
  • c198e43 Publish
  • 2856722 fix: Update adapter common tests to check for falsy (#1140)
  • ae97020 Publish
  • 8166dda fix: Update adapter common tests (#1135)
  • 49164f4 Publish
  • 40402fc fix: Fix AdapterService multi option when set to true (#1134)
  • a6615d4 Publish
  • df1daaa fix: Add whitelist and filter support to common adapter service (#1132)
  • f83c28c Publish
  • cd1a183 fix: Throw error in filterQuery when query parameter is unknown (#1131)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Pass a mongoDb Object as config.db

I'm trying to use an existing mongodb connection but passing the db object in config won't work.

db - The MongoDB connection string (e.g. mongodb://localhost:27017/events) or database object

Looking at the code (sync.js) it seems there is only connection string handling implemented...
One solution would be to just make the mongodb module importable or add database object handling.

Or did I miss something? :/

[MongoDB] Writing event fails when the hook context contains a query with a key starting with `$`

Steps to reproduce

Performs a patch/update operation on a service with any common query operators like e.g. $in.

Actual behavior

The patched/updated event is not raised.

mubsub publish operation fails with the following error: key $select must not start with '$'. Indeed for now the whole hook context object is serialized in the DB with e.g. the connection, the user, the access token, etc.

No error is raised in Feathers.

Expected behavior

The patched/updated event is raised.

Not sure which part of the hook context is required to be written in the event but probably not everything.

Feathers should catch error from the mubsub module using callbacks and at least display a message.

System configuration

NodeJS version: 8.9

Operating System: Windows 10

Module: 1.0.2

getting error collection.find(...).sort(...).limit(...).nextObject is not a function

we are using mongodb package 3.1.0 in order to connect to our mongo instance. When trying to inittialize feathers-sync like this:

feathersjsApp.configure(sync.mongodb({
  db: dbHandle,
  collection: 'feathers_events'
}))

I am getting error:

TypeError: collection.find(...).sort(...).limit(...).nextObject is not a function
at Channel.onCollection (...\node_modules\mubsub\lib\channel.js:204:14)

After quick research it seems nextObject method is not supported any more:

https://github.com/mongodb/node-mongodb-native/blob/master/CHANGES_3.0.0.md#api-changes

Is serialization of the complete context required in event ?

Starting from v1.0 not only the event data, but also the call context, is serialized as part of the event (at least for MongoDB, see https://github.com/feathersjs-ecosystem/feathers-sync/blob/master/lib/adapters/mongodb.js#L29). This already raised the following issue #83, linked to the fact the context can be a really complex object structure not really suited for serialization.

The "stringification" used to tackle this issue lead to data that are hard to read in the DB from a debug perspective. Moreover, only client data are really safe to be serialized IMHO. I wonder why the context serialization is actually required because from the client perspective only the data is sent back. I think removing it should avoid a lot of potential issues like performance overhead, failure to serialize cyclic JSON structures, etc.

Solidify default options

The first thing I noticed now that we support more transports:

  • we should make config.ur the default and remove config.db

Scale server on kubernetes

I have multiple replicas of one FeathersJS app in kubernetes. I open access to it with Service NodePort. On the client side I successfully connect to one replica, but with many replicas I have xhr poll error. The client connects to the server. It can even receive events sometimes, but on polling, I have an error.
As far as I see I have a problem because of round robin connection. The client connects to one container but then polls another.
Maybe I'm wrong and there is another reason of this error. Have anyone an experience with kubernetes and socket scaling? How properly use it?

Bulk patching a service from within another service returns null values

Steps to reproduce

Issue occurs when running node in cluster mode while using feathers-sync.

Consider the following hook in service foo after get.

const updateBar = async function (context) {
  await context.app.service('bar').patch(
    null,
    {
      text: 'bar'
    },
    {
      query: {}
    }
  );

  return context;
};

It patches all bar rows. However, when clients receive this event through websocket null will be returned for the bar rows. Server application was started using pm2 start src/ -i 2. Worth mentioning that feathers-client was used in an angular app that basically only performs a request to the API in order to reproduce the problem. This issue only occurs when using feathers-sync with multiple processes.

Expected behavior

When bulk patching (not tried create, update, remove etc) another service from within a service the values of the patched rows should be returned through websocket.

Actual behavior

When bulk patching another service from within a service null values of the patched rows are returned through websocket. Screenshot showing the returned null values.

System configuration

Running feathers-sync with redis.

Module versions (especially the part that's not working):

{
  "name": "feathers-sync-bug-api",
  "description": "",
  "version": "0.0.0",
  "homepage": "",
  "main": "src",
  "keywords": [
    "feathers"
  ],
  "author": {},
  "contributors": [],
  "bugs": {},
  "directories": {
    "lib": "src",
    "test": "test/"
  },
  "engines": {
    "node": "^8.0.0",
    "yarn": ">= 0.18.0"
  },
  "scripts": {
    "test": "yarn run eslint && yarn run mocha",
    "eslint": "eslint src/. test/. --config .eslintrc.json",
    "dev": "nodemon src/",
    "start": "node src/",
    "mocha": "mocha test/ --recursive --exit"
  },
  "dependencies": {
    "@feathersjs/configuration": "^2.0.4",
    "@feathersjs/errors": "^3.3.4",
    "@feathersjs/express": "^1.2.7",
    "@feathersjs/feathers": "^3.2.3",
    "@feathersjs/socketio": "^3.2.6",
    "feathers-hooks-common": "^4.17.10",
    "feathers-rest": "^1.8.1",
    "feathers-sync": "^1.0.3",
    "feathers-sequelize": "^3.1.2",
    "mysql2": "^1.6.1",
    "sequelize": "^4.39.0",
    "compression": "^1.7.3",
    "cors": "^2.8.4",
    "helmet": "^3.13.0",
    "serve-favicon": "^2.5.0",
    "winston": "^3.0.0"
  },
  "devDependencies": {
    "eslint": "^5.6.1",
    "mocha": "^5.2.0",
    "nodemon": "^1.18.4",
    "request": "^2.88.0",
    "request-promise": "^4.2.2"
  }
}

NodeJS version: 8.12.0

Operating System: Linux (Ubuntu 16.04)

Browser Version: Google Chrome 69.0.3497.100

React Native Version: Not applicable

Module Loader: CommonJS

Github repository: Github repository reproducing this issue

Event not fired in socket on client

When using this plugin, I can see that when an action happens, the event is fired and received by the server, but it does not get received on the client via the socket connection. When I remove this plugin, the socket events fire again. Am I missing something?

Any help is appreciated!

An in-range update of debug is breaking the build 🚨

The dependency debug was updated from 4.1.0 to 4.1.1.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

debug is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.

Status Details
  • ❌ continuous-integration/travis-ci/push: The Travis CI build failed (Details).

Commits

The new version differs by 4 commits.

  • 68b4dc8 4.1.1
  • 7571608 remove .coveralls.yaml
  • 57ef085 copy custom logger to namespace extension (fixes #646)
  • d0e498f test: only run coveralls on travis

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Plugin not published on Npm?

Hey, I couldn't find this plugin on Npm so I had to set the github repo in my package.json to get it installed. Any chance to see it on Npm :) ? Thanks

TypeError: Cannot read property 'split' of undefined

The library runs into a problem when I configure it as it's described in the example. My configuration is the following:

app.configure(sync('redis', { db: 'localhost:6379' }));

When trying to execute this code, I'm getting the error: TypeError: Cannot read property 'split' of undefined for the following line:

var proto = config.db.split('://')[0];

in file src/sync.js of the package.

This is because the variable config, at this point just contains the string "redis".

I'm guessing that we need to change the readme to use

.configure(sync({
    db: 'mongodb://localhost:27017/sync',
    collection: 'events'
  }))

and remove the "adapter" part of the Arguments section.

Real-time events doesn't fire when using Mongodb database adapter

Hi, the below is server side code:

const feathers = require('feathers');
const bodyParser = require('body-parser');
const rest = require('feathers-rest');
const socketio = require('feathers-socketio');
const memory = require('feathers-memory');
const sync = require('feathers-sync');
const MongoClient = require('mongodb').MongoClient;
const service = require('feathers-mongodb');

const app = feathers();
app.configure(rest());
app.configure(socketio());
app.configure(sync({
    db: 'mongodb://XXXX.mlab.com',
    collection: 'events'
}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use("localMemory", memory());

MongoClient.connect('mongodb://XXXX.mlab.com).then(function(db){
    app.use('/mongoDB', service({
        Model: db.collection('syncData')
    }));

    app.listen(8888);
});

When I create new data for both "mongoDB" and "localMemory", there are only "localMemory" firing the created event to client. But data actually is created at mongo database.

The client library uses 1) feathers-client v1.5.1, 2) socket-io v1.4.5
The server package version info is like below:

Thanks.

P.S. like #11. When I remove feathers-sync. The "mongoDB" real-time events works perfectly.

Setting Provider for calls from feathers sync

I was curious if it's possible / a good idea / already being done, to set the provider value to 'sync' or something when the service call is triggered by feathers sync.

I've read in the docs that it's not advised to use event listeners to modify global state when using feathers-sync, however, if the provider was set this would allow a check to run on the listener before executing.

I'd like to have my listeners modify global state and would also like to use feathers-sync so if this is possible that would be great.

An in-range update of debug is breaking the build 🚨

Version 3.2.0 of debug was just published.

Branch Build failing 🚨
Dependency debug
Current Version 3.1.0
Type dependency

This version is covered by your current version range and after updating it in your project the build failed.

debug is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.

Status Details
  • ❌ continuous-integration/travis-ci/push: The Travis CI build could not complete due to an error (Details).

Release Notes 3.2.0

A long-awaited release to debug is available now: 3.2.0.

Due to the delay in release and the number of changes made (including bumping dependencies in order to mitigate vulnerabilities), it is highly recommended maintainers update to the latest package version and test thoroughly.


Minor Changes

Patches

Credits

Huge thanks to @DanielRuf, @EirikBirkeland, @KyleStay, @Qix-, @abenhamdine, @alexey-pelykh, @DiegoRBaquero, @febbraro, @kwolfy, and @TooTallNate for their help!

Commits

The new version differs by 25 commits.

There are 25 commits in total.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

An in-range update of @feathersjs/feathers is breaking the build 🚨

The devDependency @feathersjs/feathers was updated from 3.2.3 to 3.3.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

@feathersjs/feathers is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ❌ continuous-integration/travis-ci/push: The Travis CI build failed (Details).

Commits

The new version differs by 29 commits.

  • 3bbba49 Publish
  • 17b3dc8 feat: Common database adapter utilities and test suite (#1130)
  • c73d322 feat: Allow registering a service at the root level (#1115)
  • c9f4b42 fix(package): update config to version 3.0.0 (#1100)
  • afa1cb4 fix: Added path and method in to express request for passport (#1112)
  • 9f1200f chore: Only run Saucelabs tests once in CI (#1122)
  • 57e7140 chore(package): Update superagent in group default to the latest version πŸš€ (#1095)
  • 0feb20d Verify that the error handler works on nested routes (#1096) (#1106)
  • d568627 chore(test): Update assertion format to always use strict equality (#1105)
  • fd3fc34 fix(chore): Properly configure and run code linter (#1092)
  • e894ac8 fix(chore): Remove CLI and generators that belong in their own repositories (#1091)
  • 0a2ce87 fix: make codeclimate conform to rule of three (#1076)
  • 1c74a14 Publish
  • 9da26ad fix: support a secretProvider (#1063)
  • 55de15e Publish

There are 29 commits in total.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Can't get it to work

On a single server I can see it populating events in my mongodb but as soon as I scale to 3 servers it stops working and I get socket connection errors such as

WebSocket connection to 'wss://api.example.com/socket.io/?EIO=3&transport=websocket&sid=yXLuMAYr79h-YcadAAAA' failed: Error during WebSocket handshake: Unexpected response code: 400
 Authentication timed out

An in-range update of lodash is breaking the build 🚨

The dependency lodash was updated from 4.17.10 to 4.17.11.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

lodash is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.

Status Details
  • ❌ continuous-integration/travis-ci/push: The Travis CI build could not complete due to an error (Details).

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Feathers-sync breaks when trying to authenticate

Steps to reproduce

Run feathers-sync backed by redis.

`

synk_1       | /srv/synk/node_modules/feathers-authentication/lib/socket/update-entity.js:4

synk_1       |   var app = meta.app;

synk_1       |                 ^

synk_1       |

synk_1       | TypeError: Cannot read property 'app' of undefined

synk_1       |     at Object.updateEntity (/srv/synk/node_modules/feathers-authentication/lib/socket/update-entity.js:4:17)

synk_1       |     at emitOne (events.js:101:20)

synk_1       |     at Object.emit [as _emit] (events.js:188:7)

synk_1       |     at RedisClient.<anonymous> (/srv/synk/node_modules/feathers-sync/src/redis.js:28:27)

synk_1       |     at emitTwo (events.js:111:20)

synk_1       |     at RedisClient.emit (events.js:191:7)

synk_1       |     at return_pub_sub (/srv/synk/node_modules/redis/index.js:781:18)

synk_1       |     at RedisClient.return_reply (/srv/synk/node_modules/redis/index.js:828:9)

synk_1       |     at JavascriptRedisParser.returnReply (/srv/synk/node_modules/redis/index.js:192:18)

synk_1       |     at JavascriptRedisParser.execute (/srv/synk/node_modules/redis/node_modules/redis-parser/lib/parser.js:574:12)

synk_1       |     at Socket.<anonymous> (/srv/synk/node_modules/redis/index.js:274:27)

synk_1       |     at emitOne (events.js:96:13)

synk_1       |     at Socket.emit (events.js:188:7)

synk_1       |     at readableAddChunk (_stream_readable.js:176:18)

synk_1       |     at Socket.Readable.push (_stream_readable.js:134:10)

synk_1       |     at TCP.onread (net.js:547:20)

`

Expected behavior

Should sync between servers using a redis connector provided

Actual behavior

meta is undefined

System configuration

`
const sync = require('feathers-sync');

app.configure(sync({
    db: `redis://${host}:${port}`,
  }));

`

Module versions (especially the part that's not working):
feathers: ^2.1.4
feathers-sync: ^0.1.3

NodeJS version:
v6 or v8 (both fail)

Server crashes when failing to connect to mongo or when connection is closed

Steps to reproduce

Use case 1 / 2:

Create a feathers app and configure the sync module, but do not have your mongo instance running.

import feathers from 'feathers';
import sync from 'feathers-sync';

const app = feathers().configure(sync({db: 'mongodb://localhost:27017/sync'}));
node_modules/mongodb-core/lib/topologies/server.js:321
        return self.emit('error', new MongoError(f('failed to connect to server [%s] on first connect', self.name)));
                                  ^
MongoError: failed to connect to server [localhost:27017] on first connect

Use case 2 / 2:

Kill the mongo server after you've started your feathers application process. Console log below:

node_modules/mongodb-core/lib/error.js:29
    err = new MongoError(options);
          ^
MongoError: connection 0 to localhost:27017 closed

Expected behavior

The server should be able to recover from this behavior. A catchable error should be thrown.

Actual behavior

Since the mubsub client implementation is an isolated implementation detail (https://github.com/feathersjs/feathers-sync/blob/master/src/mongodb.js#L7), I can't add an error hook in my code. So when the app can't connect to mongodb on startup, or if the connection to mongo is closed, the error bubbles up and the process crashes.

System configuration

Tell us about the applicable parts of your setup.

Module versions (especially the part that's not working):

[email protected]
[email protected]

NodeJS version: 6.0.0

Question about scalability

Please correct me if I'm wrong but this is how I understand the implementation:

If feathers-sync sends every event to every server instance then doesn't that mean your instances get diminishing returns as you continue to scale?

As an example, say I have 2 small instances, each instance can handle around 500 active users at once. Let's say each user is creating a document every 5 seconds. This means every 5 seconds 500 events are published per instance, and 500 events are received by each instance. This seems feasible.

But now let's ramp this up to 10 instances, again with each having 500 users and each user creating a document once every 5 seconds. This time, every 5 seconds 500 events are published per instance but 4500 events are received from the other instances. This is quite a heavy load.

One option here is to then reduce the amount of users each instance handles, to allow more computational power for the incoming events. But this can only go so far before it's 1 server handling a single user and millions of events per second.

Is this an accurate depiction of how feathers would scale?

Add support for WebRTC

I'm not even sure if this is possible but creating a mesh network of peer-to-peer nodes using WebRTC or something similar would be amazeballs. This would make things very fault tolerant and remove the need to run another service for the synchronization.

Less moving parts equals more better!!

Flat Rate Dedicated Sync vs Pay Per Message

It's good that you can write custom adapters to use anything as the backend for feathers-sync, but I'm wondering if there's anything that's "Pay Per Message" instead of a flat rate for dedicated resources.

Flat rate examples:

These have flat-rate prices, so they are always something like $5/month or $20/month. The price remains the same if you idle them the whole month, use their exact allocated capacity, or need more than their capacity (and your application may have performance issues, data-loss, or failure as a result).

Pay Per Message

Pay Per Message's advantages are not for everyone. If you know your price per message and your expected expenditure is less than the cost of a dedicated flat rate resource, then you would want to use Pay Per Message. If the cost were the same as or more, but you also anticipated insane usage spikes that would require upscaling your flat rate resource (which might not exist as a feature without downtime or on-demand) or you just wanted it to work without messing with that (or without messing with the entire server), Pay Per Message might be for you.

Unrelated to Pay Per Message, there is also "Received message once and only once" and "faster vs never drop unexpired messages" to consider.

Does anyone know of any Pay Per Message services that would be a valid backend for feathers-sync? I haven't decided my host yet for the project I'm currently working on, but I'd like to maintain a list of options.

An in-range update of redis is breaking the build 🚨

Version 2.8.0 of redis just got published.

Branch Build failing 🚨
Dependency redis
Current Version 2.7.1
Type dependency

This version is covered by your current version range and after updating it in your project the build failed.

redis is a direct dependency of this project this is very likely breaking your project right now. If other packages depend on you it’s very likely also breaking them.
I recommend you give this issue a very high priority. I’m sure you can resolve this πŸ’ͺ

Status Details
  • ❌ continuous-integration/travis-ci/push The Travis CI build failed Details

Commits

The new version differs by 35 commits.

  • 1380ad6 fix: test on old node versions
  • 6694c91 v.2.8.0
  • ad8355a fix: add command tests
  • 79558c5 doc: improve README readability by limiting chars to 80
  • 51fdbb7 chore: improve new add_command and add documentation
  • 0437aa4 enabled adding abritary commands
  • 4f7f1ad fix: silence auth errors on reconnect
  • 42e8bd6 chore: stop testing Node.js 7
  • 937081b fix: dependency
  • e5c8f81 fix: revert some dev dependency updates to run tests
  • 7e9dda1 chore: test node 8
  • 16632f4 fix emitting internal auth error on reconnect
  • 50774ae fix: accept UPPER_CASE commands in send_command
  • 789471b chore: update peer dependency version
  • 6934270 fix: always copy subscribe unsubscribe arguments

There are 35 commits in total.

See the full diff

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

Memory leak

I pretty sure I have a really big memory leak

I'm using memwatch-next and it regularly report heap growth such as

Memory leak detected:
 { growth: 512,
  reason: 'heap growth over 5 consecutive GCs (12s) - 409.2 mb/hr' }

This is resulting in the app crashing fairly regularly

Using chrome inspect i taken some snapshots while doing several uploads and one thing that keeps increasing is the strings. On the screenshots attached the thing that looks strange is when you view the details on the string the seem to be a never ending nested "event created"

screen shot 2018-09-30 at 11 56 03

screen shot 2018-09-30 at 11 56 15

One thing I believe this is due to is the use of debug which is logging every event to memory. So if you have a lot of events it going to cause issue as far as I can tell. debug doesn't serve any purpose in production so there should be an option to turn it off, or preferable have it turned of by default which the option to turn it on if needed.

Happy to be proved wrong but app seem to have consistent memory usage when sync isn't running.

Does not send service events to client if service is connected to moongoose

Steps to reproduce

Tell us what broke. The more detailed the better.

Feathers-sync does work with a service that is not connected to moongoose
Feathers-sync does not work with a service that is connected to moongoose

I will note, both services do send the result back to the client, but the created event is only being pushed out to the service that is not connected to moogoose

 feathers-sync will sync via adapter: mongodb  +0ms
  feathers-sync setting up database mongodb://localhost:27017/sync +2ms
  feathers-sync subscribing to handler todo-mongoose created +27ms
  feathers-sync subscribing to handler todo-mongoose updated +0ms
  feathers-sync subscribing to handler todo-mongoose removed +0ms
  feathers-sync subscribing to handler todo-mongoose patched +0ms
  feathers-sync subscribing to handler todo created +1ms
  feathers-sync subscribing to handler todo updated +0ms
  feathers-sync subscribing to handler todo removed +0ms
  feathers-sync subscribing to handler todo patched +0ms
  feathers-sync emitting event to channel todo-mongoose created +4s
  feathers-sync emitting event to channel todo created +126ms
  feathers-sync got event, calling old emit todo created +19ms

It shows that it is emitting event for the todo-mongoose (service that is connected to mongoose) but client does not receive event, but client does receive the event for the channel todo created event.

https://github.com/travisbmiller/feathers-sync-test

Expected behavior

Should send all service events to client

Actual behavior

Does not send service any events to client for a service that is connected to mongoose

System configuration

Tell us about the applicable parts of your setup.

Module versions (especially the part that's not working):
"feathers": "^2.0.3",
"feathers-hooks": "^1.7.1",
"feathers-mongoose": "^3.6.1",
"feathers-rest": "^1.5.2",
"feathers-socketio": "^1.4.2",
"feathers-sync": "^0.1.2",
"mongoose": "^4.7.5"

NodeJS version:
6.9.1

Operating System:
Mac Os 10.12.2 / and Tested on AWS

Browser Version:
Chrome / Safari / firefox

Multiple services using the same Redis

If multiple services on the same cluster use the same redis client with feathers-sync, there's a possibility for collisions. This will only happen if the services have the same name, but it's still something to be concerned about.

If I get time I'll do a PR to fix it, should probably just need to add an option like prefix for redis, and change

var ev = path + ' ' + event;

For now we're just using AMQP for one service and Redis for the other, since we have both.

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.