Git Product home page Git Product logo

meteor-mongo-counter's Introduction

konecty-mongo-counter

Atomic counters stored in MongoDB.

Incrementing a counter returns consecutive integers (1, 2, 3...), with the counter stored in the database.

It is safe to make concurrent calls to incrementCounter and decrementCounter. If the current value of a counter is 6 and two Meteor methods call incrementCounter at the same time, one will receive 7 and the other 8.

This package is called mongo-counter because it works directly with MongoDB's facilities for atomic updates; it doesn't go through Meteor's collection code. (Thus it only works with Meteor deployments that use a MongoDB database. If, for example, a SQL database was being used instead, there would need to be a "sql-counter" package to implement atomic counters in SQL).

Note that counters are not stored in a Meteor document: this package doesn't increment a field in a document inside of a Meteor collection. But when you increment or decrement a counter, you can take the new value of the counter that is returned to you and store that value in a Meteor document if you want.

Counters are not themselves a reactive data source, but you can store the counter value into a reactive data source such as a Meteor document whenever you increment or decrement a counter.

Version

1.1.0

Meteor linker supported: This implementation works with both pre-linker Meteor (0.6.4.1 and below) and the new "linker" version of Meteor (0.6.5-rc12 and above).

API

Note that this API is defined on the server only, and that these functions are not defined in the client. To access them from the client, create a Meteor method on the server that calls the API, and then call the method from the client.

Create a Meteor Collection to hold the counter.

Counters = new Mongo.Collection('counters');

Pass the Counters collection to each of the API described below.

incrementCounter

incrementCounter(collection, name, [amount])   server

Increments a database counter and returns the new value.

Arguments

collection: Meteor Collection
The Collection that will hold all the Mongo Counters.
name: string
The name of the counter to increment.
amount: integer
The amount to increment the counter by, defaulting to one.

Increments the counter named name in the database, and atomically returns the new value. New counters conceptually start at zero, so if you increment a new counter by one you will receive one on the first call.

decrementCounter

decrementCounter(collection, name, [amount])   server

Decrements a database counter and returns the new value.

Arguments

collection: Meteor Collection
The Collection that will hold all the Mongo Counters.
name: string
The name of the counter to decrement.
amount: integer
The amount to decrement the counter by, defaulting to one.

Decrements the counter named name in the database, and atomically returns the new value.

setCounter

setCounter(collection, name, value)   server

Sets a counter.

Arguments

collection: Meteor Collection
The Collection that will hold all the Mongo Counters.
name: string
The name of the counter to set.
value: integer
The value to set the counter to.

Sets the counter to the specified value.

This is primarily useful for setting a new counter to an initial value. (If a counter was currently 10 and one method called incrementCounter while another simultaneously called setCounter with a value of 0, it would be indeterminate whether the first method received 11 or 1).

Using a counter for a humanly readable id

Counters can be used when you want to create a humanly readable identifier that is guaranteed to be unique, such as an order or invoice number.

Typically you wouldn't want to use a counter number as the _id of a document, unless the document is only ever created on the server.

A pattern that works with creating documents in the client is to allow Meteor to create its usual random string _id field, and then put the humanly readable identifier in another field (such as "orderNumber") with a method call to the server. This allows the counter field to be filled in when the client has a connection to the server, without making the client wait if the Internet connection is momentarily slow or disconnected.

Implementation

This package implements the "Counters Collection" technique described in the MongoDB documentation Create an Auto-Incrementing Sequence Field.

Using the Mongo findAndModify method makes incrementing the counter and reading the new value atomically safe. (If we first incremented the counter field using update and then read the new value using find, two simultaneous calls to incrementCounter could increment the counter twice and then both return the same doubly incremented number).

Since Meteor doesn't yet support Mongo's findAndModify, the implementation accesses Mongo directly without going through a Meteor Collection.

The Mongo collection used to store counter values is "awwx_mongo_counter". Accessing this collection with a Meteor Collection isn't recommended, because changes made by incrementCounter aren't reported back to Meteor.

meteor-mongo-counter's People

Contributors

awwx avatar engelgabriel avatar marceloschmidt avatar sampaiodiego avatar shriharshmishra avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

meteor-mongo-counter's Issues

Set initial value once

Hi there,

Was trying to figure out if it is possible to set an initial starting value for the counter (say 100)?

My initial idea was to add it to test to see if the counter was zero inside a Meteor.startup call and then set to 100 if so but don't think there is a getter for a counter?

Thanks

Coffeescript dependency too low now. Update required.

Please update coffeescript dependency to the latest version.

I have been unable to make required updates to some other packages because they require at least version 2.0.3_3 of coffeescript. konecty:mongo-counter sets maximum compatible version of coffeescript at 1.0.2.

Error...

I am running this ...

getNextSequence: function () {
    incrementCounter('box_id', 1); 
}

as a meteor method using...

Meteor.call('getNextSequence');

I get the following errors in my terminal...

Exception while invoking method 'getNextSequence' TypeError: Object box_id has no method 'rawCollection'
I20150508-19:33:23.698(0)?     at getCounterCollection (packages/konecty:mongo-counter/counter.coffee:2:14)
I20150508-19:33:23.698(0)?     at callCounter (packages/konecty:mongo-counter/counter.coffee:6:14)
I20150508-19:33:23.698(0)?     at _incrementCounter (packages/konecty:mongo-counter/counter.coffee:20:12)
I20150508-19:33:23.698(0)?     at [object Object].Meteor.methods.getNextSequence (app/server/methods.js:41:16)
I20150508-19:33:23.698(0)?     at [object Object].methodMap.(anonymous function) (packages/meteorhacks:kadira/lib/hijack/wrap_session.js:160:1)
I20150508-19:33:23.699(0)?     at maybeAuditArgumentChecks (packages/ddp/livedata_server.js:1617:1)
I20150508-19:33:23.699(0)?     at packages/ddp/livedata_server.js:648:1
I20150508-19:33:23.699(0)?     at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20150508-19:33:23.699(0)?     at packages/ddp/livedata_server.js:647:1
I20150508-19:33:23.699(0)?     at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)

docs need updating

Hi, thanks for turning on Issues.

We have trouble with this package for a while because the function sig changed, but the readme doesn't reflect the change yet. Did you see there is a pull request for the doc fix?

Cheers!

incrementCounter returns undefined after upgrading Meteor

It looks like upgrading Meteor to version 1.4 broke this package.

I created a new test app with just the following code added, and it prints undefined 10 times

Meteor.startup(() => {
    Counters = new Mongo.Collection('counters');

    for(i=0;i<10;i++)
        console.log(incrementCounter(Counters, "index"))
});

typescript import

When I import to type script like

import "meteor/konecty:mongo-counter";

incrementCounter() is undefined.

When I import like: (as described in meteor/meteor#6177)

import {incrementCount} from  "meteor/konecty:mongo-counter";

the build can't find the module.

Not sure if I'm doing something wrong or if there's a problem with the package...

rawCollection not defined

I am running Meteor 1.1 and see no method rawCollection

Exception while invoking method 'insertBracket' TypeError: Object bracket_counter has no method 'rawCollection'
I20150402-06:08:22.742(-4)? at getCounterCollection (packages/konecty:mongo-counter/counter.coffee:2:14)
I20150402-06:08:22.743(-4)? at callCounter (packages/konecty:mongo-counter/counter.coffee:6:14)
I20150402-06:08:22.743(-4)? at incrementCounter (packages/konecty:mongo-counter/counter.coffee:20:12)
I20150402-06:08:22.743(-4)? at [object Object].Meteor.methods.insertBracket (app/server/methods/bracketMethods.js:25:15)
I20150402-06:08:22.743(-4)? at maybeAuditArgumentChecks (packages/ddp/livedata_server.js:1617:1)
I20150402-06:08:22.744(-4)? at packages/ddp/livedata_server.js:648:1
I20150402-06:08:22.744(-4)? at [object Object].
.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20150402-06:08:22.744(-4)? at packages/ddp/livedata_server.js:647:1
I20150402-06:08:22.744(-4)? at [object Object]..extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20150402-06:08:22.744(-4)? at [object Object].
.extend.protocol_handlers.method (packages/ddp/livedata_server.js:646:1)

I am using it like so:

Brackets.insert(
{
bracketId: incrementCounter(COUNTER_BRACKET),
...

TypeError: Object orderNumber has no method 'rawCollection'

Here's my server code:

Meteor.methods({
    //uses meteor mongo-counter to get an atomic number
    getNextOrderNumber: function() {
        return incrementCounter('orderNumber');
    }
});

which throws this exception:

I20150414-17:22:41.490(2)? Exception while invoking method 'getNextOrderNumber' TypeError: Object orderNumber has no method 'rawCollection'
I20150414-17:22:41.491(2)? at getCounterCollection (packages/konecty:mongo-counter/counter.coffee:2:14)
I20150414-17:22:41.491(2)? at callCounter (packages/konecty:mongo-counter/counter.coffee:6:14)
I20150414-17:22:41.491(2)? at incrementCounter (packages/konecty:mongo-counter/counter.coffee:20:12)
I20150414-17:22:41.491(2)? at [object Object].Meteor.methods.getNextOrderNumber (app/server/methods.js:16:16)
I20150414-17:22:41.491(2)? at maybeAuditArgumentChecks (packages/ddp/livedata_server.js:1617:1)
I20150414-17:22:41.491(2)? at packages/ddp/livedata_server.js:648:1
I20150414-17:22:41.491(2)? at [object Object].
.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20150414-17:22:41.491(2)? at packages/ddp/livedata_server.js:647:1
I20150414-17:22:41.491(2)? at [object Object]..extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20150414-17:22:41.492(2)? at [object Object].
.extend.protocol_handlers.method (packages/ddp/livedata_server.js:646:1)
I20150414-17:22:41.492(2)? at packages/ddp/livedata_server.js:546:1

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.