Git Product home page Git Product logo

meteor-synced-cron's Introduction

percolate:synced-cron

A simple cron system for Meteor. It supports syncronizing jobs between multiple processes. In other words, if you add a job that runs every hour and your deployment consists of multiple app servers, only one of the app servers will execute the job each time (whichever tries first).

Migrated from percolate:synced-cron littledata:synced-cron

Since the original creator of the project could no longer maintain it, we had to migrate the package to another organisation to allow further maintenance and updates.

To migrate you can simply run

$ meteor remove percolate:synced-cron && meteor add littledata:synced-cron

Installation

$ meteor add littledata:synced-cron

API

Basics

To write a cron job, give it a unique name, a schedule and a function to run like below. SyncedCron uses the fantastic later.js library behind the scenes. A Later.js parse object is passed into the schedule call that gives you a huge amount of flexibility for scheduling your jobs, see the documentation.

SyncedCron.add({
  name: 'Crunch some important numbers for the marketing department',
  schedule: function(parser) {
    // parser is a later.parse object
    return parser.text('every 2 hours');
  },
  job: function() {
    var numbersCrunched = CrushSomeNumbers();
    return numbersCrunched;
  }
});

To start processing your jobs, somewhere in your project add:

SyncedCron.start();

Advanced

SyncedCron uses a collection called cronHistory to syncronize between processes. This also serves as a useful log of when jobs ran along with their output or error. A sample item looks like:

{ _id: 'wdYLPBZp5zzbwdfYj',
  intendedAt: Sun Apr 13 2014 17:34:00 GMT-0700 (MST),
  finishedAt: Sun Apr 13 2014 17:34:01 GMT-0700 (MST),
  name: 'Crunch some important numbers for the marketing department',
  startedAt: Sun Apr 13 2014 17:34:00 GMT-0700 (MST),
  result: '1982 numbers crunched'
}

Call SyncedCron.nextScheduledAtDate(jobName) to find the date that the job referenced by jobName will run next.

Call SyncedCron.remove(jobName) to remove and stop running the job referenced by jobName.

Call SyncedCron.stop() to remove and stop all jobs.

Call SyncedCron.pause() to stop all jobs without removing them. The existing jobs can be rescheduled (i.e. restarted) with SyncedCron.start().

To schedule a once off (i.e not recurring) event, create a job with a schedule like this parser.recur().on(date).fullDate();

Configuration

You can configure SyncedCron with the config method. Defaults are:

  SyncedCron.config({
    // Log job run details to console
    log: true,

    // Use a custom logger function (defaults to Meteor's logging package)
    logger: null,

    // Name of collection to use for synchronisation and logging
    collectionName: 'cronHistory',

    // Default to using localTime
    utc: false,

    /*
      TTL in seconds for history records in collection to expire
      NOTE: Unset to remove expiry but ensure you remove the index from
      mongo by hand

      ALSO: SyncedCron can't use the `_ensureIndex` command to modify
      the TTL index. The best way to modify the default value of
      `collectionTTL` is to remove the index by hand (in the mongo shell
      run `db.cronHistory.dropIndex({startedAt: 1})`) and re-run your
      project. SyncedCron will recreate the index with the updated TTL.
    */
    collectionTTL: 172800
  });

Logging

SyncedCron uses Meteor's logging package by default. If you want to use your own logger (for sending to other consumers or similar) you can do so by configuring the logger option.

SyncedCron expects a function as logger, and will pass arguments to it for you to take action on.

var MyLogger = function(opts) {
  console.log('Level', opts.level);
  console.log('Message', opts.message);
  console.log('Tag', opts.tag);
}

SyncedCron.config({
  logger: MyLogger
});

SyncedCron.add({ name: 'Test Job', ... });
SyncedCron.start();

The opts object passed to MyLogger above includes level, message, and tag.

  • level will be one of info, warn, error, debug.
  • message is something like Scheduled "Test Job" next run @Fri Mar 13 2015 10:15:00 GMT+0100 (CET).
  • tag will always be "SyncedCron" (handy for filtering).

Caveats

Beware, SyncedCron probably won't work as expected on certain shared hosting providers that shutdown app instances when they aren't receiving requests (like Heroku's free dyno tier or Meteor free galaxy).

Contributing

Write some code. Write some tests. To run the tests, do:

$ meteor test-packages ./

License

MIT. (c) Percolate Studio, originally designed and built by Zoltan Olah (@zol), now community maintained.

Synced Cron was developed as part of the Verso project.

meteor-synced-cron's People

Contributors

awesomepan avatar creitz avatar faburem avatar grigio avatar grubba27 avatar johanbrook avatar kurounin avatar realyze avatar richsilv avatar roelvan avatar sachag avatar storytellercz avatar thegame2500 avatar timbrandin avatar tmeasday avatar zol 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

meteor-synced-cron's Issues

SyncedCron is not defined on production

Hi, not sure why this is happeneing but I get an error Uncaught ReferenceError: SyncedCron is not defined on my digital ocean server.

My cron.js file

Meteor.startup(function(){
  SyncedCron.add({
    name: 'Clear notifications that are 5 days old',
    schedule: function(parser) {
      // parser is a later.parse object
      return parser.text('every day');
    }, 
    job: function() {
      // current epoch - milli seconds in 5 days = epoch 5 days ago
      var epoch = new Date().getTime();
      var fiveDaysAgo = epoch - (1000 * 60 * 60 * 24 * 5)
      Notifications.remove({ epoch: { $lte: fiveDaysAgo}})
    }
  });

  SyncedCron.start();
})

Using cronHistory collection in application

Firstly, thanks for such a brilliant package.

I want to use the cronHistory collection in my application but i believe its not currently possible due to the package not exporting the collection (api.export).

Is this correct or am i missing something?

Can this be added?

Thanks,

Luke

How to not interrupt previous job if it is time for the job to start again?

I have a job that I want to run everyone 1 minute. But sometimes it takes more than one minute to complete the job, when this happens, that job is terminated in the middle of it running and starts a new job.

Is there a way to let the prevous job finish before starting over again, if it is still running? Or treat the new job as a new instance that does not stop the prevous running job if the new job is started before the old one is done?

Basically it is dangerous in my app to interrupt the job so I want a way to prevent the job being stopped by the next scheduled run when the job getting ran again.

Add support for sending an email on job end

Especially useful on errors. Thinking of something like the following json object, using meteor's email package:

email: {
  from: ...
  to:
  onDone: true
  onError: true
} 

I also noticed there seems to be no support for async jobs, which is easily solved using futures.

I can work on a PR for both, if needed.

Meteor Galaxy

This package doesnt appear to be working for me when using meteor deploy. Any work-arounds?

syncedCron.start() is not running jobs again after restart of Meteor

When restarting the Meteor server locally and also when running Meteor as an Node.js application using Supervisor on Debian 8 server, previously scheduled jobs are not activated and run again.

If I add a new scheduled job, the new job will work, but the previous jobs will not run. At restart, same procedure again.

I have placed the syncedCron.start() in a lib.js file inside a (Meteor.isServer) statement, should it rather be within a Meteor.startup statement?

collectionName:null

Is there a way to disable the insert on the collection? something like

 collectionName:null

this thrown an error

Is there a way to schedule a job to run once in the future?

  addCronMail: function(id, transfer) {

    SyncedCron.add({
      name: id,

      schedule: function(parser) {
        return parser.recur().on(transfer.invoice.dueDate).fullDate();
      },

      job: function() {
        Meteor.call('sendMail',transfer);
        FutureEmails.remove(id);
        SyncedCron.remove(id);
        return id;
      }
    });
  }

transfer.invoice.dueDate having the form of "2014-12-24T00:00:00-05:00"

SyncedCron job not running on Heroku production server

Hi,

This probably isn't a synced-cron bug in itself, but I'd appreciate your thoughts. I have a SyncedCron job that works perfectly in development, but when I push to my server (on Heroku), it never fires. I've tried having the job in server/jobs/ and moving it to the bin directory.

What could be preventing this?

Here's the job itself:

SyncedCron.add
  name: 'Import products'
  schedule: (parser) ->
    parser.text('every 24 hours')
  job: ->
    Meteor.call 'import_product_json'

Meteor.startup ->
  SyncedCron.start()

intendedAt not working on heroku

Say I have two servers running the same code base, and I have a SyncedCron job set up to run every 2 hours. Will it run on both servers at the same time? Or will only one server execute the job?

Ideally, I would like the job to be only executed once (twice would be redundant). Whichever server "gets to it first" would run it and the other one wouldn't need to.

No version 1.2.1 on Atmosphere?

Why am I only getting up to version 1.1.0 when using meteor update? There isn't a SyncedCron.config on version 1.1.0.

Thanks.

some options work in Meteor.startup, some do not

it makes sense why, i guess... when i set a custom logger and utc: true AND call start() in the same startup block, the logger works but the time setting is ignored

i've been trying to figure this out in the background for weeks, and it finally hit me after reading this comment: #15 (comment)

i've never run into this issue with other packages... is it common, or something that can be refactored, or should it at least be called out in the docs?

Can't schedule something to run once and only once

Apologies for duplicating an issue mentioned in #13, but I just wanted to be sure it got to the right place. When I schedule something to run exactly once in the future as below, I get the following error (also below).

if (Meteor.isServer) {
SyncedCron.add({
name: 'Crunch some important numbers for the marketing department',
schedule: function(parser) {
// parser is a later.parse object
return parser.text('at 20:06 on the 23rd day of September in 2014');
},
job: function() {
console.log('crunching numbers')
}
});

}

=> App running at: http://localhost:3000/
I20140923-20:06:00.014(7)? SyncedCron: Starting "Crunch some important numbers for the marketing department".
I20140923-20:06:00.016(7)? crunching numbers
I20140923-20:06:00.017(7)? SyncedCron: Finished "Crunch some important numbers for the marketing department".
I20140923-20:06:00.030(7)? Exception in setTimeout callback: TypeError: Cannot call method 'getTime' of undefined
I20140923-20:06:00.030(7)? at scheduleTimeout (packages/synced-cron/synced-cron-server.js:260)
I20140923-20:06:00.030(7)? at Object.SyncedCron._laterSetTimeout (packages/synced-cron/synced-cron-server.js:245)
I20140923-20:06:00.030(7)? at scheduleTimeout (packages/synced-cron/synced-cron-server.js:223)
I20140923-20:06:00.031(7)? at packages/synced-cron/synced-cron-server.js:265
I20140923-20:06:00.031(7)? at _.extend.withValue (packages/meteor/dynamics_nodejs.js:56)
I20140923-20:06:00.031(7)? at packages/meteor/timers.js:6
I20140923-20:06:00.031(7)? at runWithEnvironment (packages/meteor/dynamics_nodejs.js:108)

How to log to Winston?

Since I'm using Papertrail to collect my Meteor application logs, I'd love to be able to send logging details from SyncedCron to Winston which will then forward to Papertrail. Is this supported and if so, how to integrate? Thanks!

Run job only once or not at all

Hi Zoltan,

maybe is a bit stupid question, but how can I set a job to run only once?
For example in 7 days from now, run job "remind user" ? And when the time comes I want to check if it's still necessary to remind the user, if not I want to prevent running the job at all.

I appreciate your help, thanks ;)

How to add multiple jobs

Hi,

I think I'm missing something very simple here. I am trying to run 2 jobs with this package but only the first one is being run and not the second one. Can we not add jobs by just calling SyncedCron.add multiple times? Like so:

SyncedCron.add({
  name: 'Check if 24 hours have elapsed for pending reservations',
  schedule: function(parser) {
    // parser is a later.parse object
    return parser.text('every 15 mins');
  },
  job: function() {
    Meteor.call('checkRes');
  }
});

SyncedCron.add({
  name: 'Routine transaction processing every 12 hours',
  schedule: function(parser) {
    // parser is a later.parse object
    return parser.text('every 12 hours');
  },
  job: function() {
    checkTransaction();

    holdDeposit();

    releaseDeposit();
  }
});

SyncedCron.start();

Question About Multiple Servers

The description says this works across multiple processes, but can it work with multiple Meteor servers running the same code? Looking through the source, I don't see where collection.find() is ever used; it seems this package only inserts and updates jobs but never reads what jobs are stored in the collection.

Thank you for any clarification you can provide.

Options : not working for me

Hi Zol,

when I copy paste your "option" code I can't make it work, do you have an idea what I do wrong? My js file is in /server...

SyncedCron.options: {
log: true, // log debug info to the console
collectionName: 'cronHistory' // default name of the collection used to store job history,
utc: false // use UTC for evaluating schedules (default: local time)
}

Implementing this package is a great idea (don't know if you found a better solution btw), but no docs for "option" onLater Github :(

Thanks for your help

Can I use synced-cron to time a single server event?

I'm building an auction system where the bidding on each item ends at a specific time. When an auction ends, certain operations should be executed. This is a one-time event, of course.

SyncedCron seems like the most robust solution for timed server events โ€“ is there an easy way of creating a job that runs once at a specific time in the future?

Thanks!

Running specific task.

I can add several tasks to it but SyncedCron.start(), starts them all.
Any method of adding several tasks and starting a specific task only?

is job executed?

Is there any way to find out if an once-off( non-recurring) job has been executed?

Properly rerun cron tasks if server restarts

Lets say for example the time is now 00:00.

I schedule a job to run every hour, so the next run time should be 01:00.

Then suddenly my server crashes and restarts at 00:30, will the job still continue to run at 01:00? Or will it run at 01:30 instead?

I think the former behavior is preferred but I'm not sure if this packages does that.

Scheduled jobs that run 'immediately' aren't properly synchronized

Unfortunately, Later's scheduling is more flexible than I had anticipated when I initially designed SyncedCron and nextScheduledAtDate() is wrong in some cases. I'll try my best to explain. If you set a schedule in the future, like you'd typically do with cron, the behavior will be as expected. For example, if the schedule dictates a job to run at say 10pm every Sunday, if you call nextScheduledAtDate() on say Wednesday, it will return 10pm Sunday as the next scheduled at date. This is typically how we use SyncedCron in our projects.

However, if you set a schedule that overlaps with the current time, when you call nextScheduledAtDate() that schedule will be re-evaluated at that moment. As an example, if you set a scheduled job to run on Wednesday, and it's Wednesday, SyncedCron will try to run the job as soon as you call start(). Likewise, whenever you call nextScheduledAtDate() on Wednesday, it will always return the current time thinking that the job needs to be scheduled immediately. This is the issue you're experiencing.

This is a pretty big issue for SyncedCron in general as this class of 'immediately scheduled' won't end up being properly synchronized.

How do I direct the cron job at who ever created it ?

I would like to send a notification to the user who has created the job. How do I go about achieving this ?
Can I somehow store the userid who created the job and then retrieve it in the "job" method while the cronjob gets executed ?

comparing scheduled time and current time

Hi,

I've created a few scheduled messages and am using parser.text so that I can say something like "at 10:00am".

Basically I want to have a logic check where I compare the scheduled date and time and the current time, and then take an action. What's the best way to access the message's scheduled date and time?

Thanks,
John

Adding range to fire job within the range

Hi,

Suppose i have two dates date1= Tue Mar 24 2015 12:25:00 GMT+0530 (IST) and date2=Tue Mar 31 2015 12:25:00 GMT+0530 (IST) and both are future dates.
Now i want my job to fire every day at 12:25 starting from march 24 2015 to march 31' 2015.How can i set the schedule in that case?

Thanks,
Karabi

Impossible to set certain options

Certain SyncedCron.options (collectionName, utc) are used immediately after the options definition thus not giving the application author a chance to override them.

Undefined is not a function

Hi ,
I am getting undefined is not a function on synced-cron-server.js (line 9) error when i start my meteor app. i just upgraded to version 0.9.1.1. I dont know if it is the instantiation of the cronHistory collection (which has changed to new Mongo.Collection(...)). my jobs where wrking perfectly before the upgrade. Any thoughts on this please.
Joshua

expireAfterSeconds

Nice work!

  • The below code done't seems work correctly

-- app

SyncedCron.options.collectionTTL = 600;

-- package

SyncedCron._collection._ensureIndex({startedAt: 1 },
        { expireAfterSeconds: options.collectionTTL } );
You cannot use ensureIndex() to change the value of expireAfterSeconds. 
Instead use the collMod database command in conjunction with the index collection flag.
  • the recommendation is to use
db.runCommand({collMod: "cronHistory", index: {keyPattern: {startedAt:1}, expireAfterSeconds: 500}}

Any thoughts?

control actions from client side

hey i'm trying to send mails with synced-cron, but i need full control over it on the client side.
is there a reactive way to make list of future actions?

I tried using Meteor.call and return the nextScheduledAtDate function into session but it does not change according to the jobs process .

Unable to drop index

Hello,

First of all many thanks for your awesome work.
I have an issue, when I try to drop index by: db.cronHistory.dropIndex({startedAt: 1});
It returns with this error:
{ "ok" : 0, "errmsg" : "can't find index with key:{ startedAt: 1.0 }" }

Any solution / suggestion?

options.collectionName does not seem to work

I added this to my js file just before the SyncedCron.start()

SyncedCron.options = {
    log: false,
    collectionName: 'tada',
    utc: false ,
    purgeLogsAfterDays: 7
}

I can switch off some of the console logging using the log property - but my history of jobs are stille in the db.cronHistory collection.

Please note the "=" and not ":" as the example in the README.md specifies.

The output from meteor list:

percolatestudio:synced-cron    0.3.0

Cannot run jobs due to Mongo duplication error

Hi! Great package! We use it at Lookback for running email jobs for different timezones.

However, this has magically stopped working. From the logs, I read:

SyncedCron: Not running "Run Daily Timezone Jobs" again.

from line 134 for each time a new job is gonna run.

The thing is, we're only running the app on one instance, and there cannot be any already existing recordings, due to their unique names and intendedAt property (them being indexes).

I even cleared the cronHistory collection, but after a couple of hours, it kept logging the duplication message.

Any idea what I'm doing wrong? I've debugged everything up until this.

Dump

db.cronHistory.find({name: 'Run Daily Timezone Jobs'}).sort({intendedAt: -1})
{ "_id" : "MR3zMKuyCtiYNHDNf", "finishedAt" : ISODate("2014-11-19T09:00:00.038Z"), "intendedAt" : ISODate("2014-11-19T09:00:00Z"), "name" : "Run Daily Timezone Jobs", "result" : null, "startedAt" : ISODate("2014-11-19T09:00:00.001Z") }
{ "_id" : "TeQDcCSukmJRujNRj", "finishedAt" : ISODate("2014-11-19T08:00:00.110Z"), "intendedAt" : ISODate("2014-11-19T08:00:00Z"), "name" : "Run Daily Timezone Jobs", "result" : null, "startedAt" : ISODate("2014-11-19T08:00:00.001Z") }
{ "_id" : "2MwJfZpiCbDs4Wgnp", "finishedAt" : ISODate("2014-11-19T07:00:00.232Z"), "intendedAt" : ISODate("2014-11-19T07:00:00Z"), "name" : "Run Daily Timezone Jobs", "result" : null, "startedAt" : ISODate("2014-11-19T07:00:00.002Z") }
{ "_id" : "t2YvJk5FMSpAEL2ha", "finishedAt" : ISODate("2014-11-19T06:00:01.580Z"), "intendedAt" : ISODate("2014-11-19T06:00:00Z"), "name" : "Run Daily Timezone Jobs", "result" : null, "startedAt" : ISODate("2014-11-19T06:00:00.002Z") }
{ "_id" : "tjz5mxZfnmCa5cw6Q", "finishedAt" : ISODate("2014-11-19T05:00:00.067Z"), "intendedAt" : ISODate("2014-11-19T05:00:00Z"), "name" : "Run Daily Timezone Jobs", "result" : null, "startedAt" : ISODate("2014-11-19T05:00:00.001Z") }
{ "_id" : "84jbCFdbjwYFdnanC", "finishedAt" : ISODate("2014-11-19T04:00:00.057Z"), "intendedAt" : ISODate("2014-11-19T04:00:00Z"), "name" : "Run Daily Timezone Jobs", "result" : null, "startedAt" : ISODate("2014-11-19T04:00:00Z") }

Make it possible to run a cron job as a method in development

It's a really common pattern to write something like

var doSomething = function() {
}

SyncedCron.add({
  name: 'doSomething',
  schedule: function(parser) {
    return parser.cron('0 0 * * *'); //daily
  }, 
  job: doSomething
});

if (Meteor.settings.public.environment === 'development') {
  Meteor.methods({
    doSomething: doSomething
  });
}

It'd be nice if SC could just do this for us.

Disable console log

I've a cron that runs "every 1 seconds" so it prints tons of messages on terminal. Is there a way to disable this logs?

Allow error to be retrieved in job

It would be really nice to get the error available in the job

  SyncedCron.add
    name: "Get some data"
    schedule: (parser) ->
      parser.text('at 5:00 am')
    job: (error) ->
      if error then return error else return "completed"

This would be very useful if you want to provide information why the job has failed. Thanks

Calling SyncedCron.start() in multiple packages

When using synced-cron in multiple packages, how should you call SyncedCron.start()?

It seems like calling it one time in each package makes each job run as many times as there are packages, which is obviously not what we want.

Is the only option to call it once from the core app itself?

Cron start newly added jobs

Missing a way to start new cron jobs that are created dynamically.

And the start function can only be run once as it contains Meteor.startup
How to I otherwise restart all projects?

Lost all jobs when redeploying or restarting web server

When I kill and restart meteor on my localhost:3000, the jobs I created all disappeared. Is there a way for me to keep the jobs in memory, such as a MongoDB collection, and then to restart the jobs when the server boots up again?

Also store upcoming jobs

If I'm not mistaken right now the package only logs past jobs? It would be really useful if it had entries for upcoming scheduled jobs, too.

Every second, have intended_at by the beginning of the second

Hi there-

I'm using a time series architecture for my db and I would like to run a job at the beginning of every second. I see that in my cronHistory collection the jobs are running correctly

{
    "_id" : "yAN2jN5aT4HgGQPcY",
    "intendedAt" : ISODate("2015-09-22T20:21:54Z"),
    "name" : "Minute Valuation",
    "startedAt" : ISODate("2015-09-22T20:21:54.693Z"),
    "finishedAt" : ISODate("2015-09-22T20:21:54.720Z"),
    "result" : null
}

but some of the writes are not going through. I believe this is due to my schedule function

  schedule: function(parser) {
    return parser.recur().every(1).second();
  }

Is there a way for me to make sure that the job gets started at the start of every second? ie. The 'startedAt' is closer to ISODate("2015-09-22T20:21:54.000Z").

It could be that this is already happening and that the job itself is not performant and is slowing down the queue.

Thanks!

cron job stopped running, had to restart meteor

i had a cron job running once per second, it watches a mongo collection and executes any commands it finds in there that match its criteria. it was running fine for several weeks and then it just stopped. when i restarted my meteor app it came online again.

not sure what logs might help with troubleshooting this, but i have access to everything. please help!

Preventing jobs from running at all?

This may be somewhat of a niche use case, but I'd love to have a way to prevent a job from being scheduled from within the job itself, in order to let the end user enable to disable jobs right from Telescope's web UI.

In other words, let me return false somewhere to prevent the message SyncedCron: scheduled "scheduleNewsletter" next run @Mon Jan 05 2015 00:00:00 GMT+0900 (JST) from being logged at all, if that makes sense?

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.