Giter Site home page Giter Site logo

agendash's Introduction

Agendash

A Dashboard for Agenda.


Features

  • Job status auto-refreshes: 60-second polling by default.
  • Schedule a new job from the UI.
  • Dive in to see more details about the job, like the json data.
  • Requeue a job. Clone the data and run immediately.
  • Delete jobs. Useful for cleaning up old completed jobs.
  • Search jobs by name and metadata. Supports querying by Mongo Object Id.
  • Pagination
  • Responsive UI

Screenshots

Dashboard

Auto-refresh list of jobs


Create jobs

See job details, requeue or delete jobs


Search by name, metadata, job status

Search for a job by name or metadata


Responsive UI

Mobile UI small devices

Mobile UI extra small devices


Troubleshooting

Index for sorting

It may be required to create the following index for faster sorting (see #24)

db.agendaJobs.ensureIndex({
    "nextRunAt" : -1,
    "lastRunAt" : -1,
    "lastFinishedAt" : -1
}, "agendash")

Roadmap

  • Get more test coverage
  • Add middlewares for fastify, and other express-like libraries
  • You decide! Submit a feature request

Install

npm install --save agendash

Note: Agendash requires mongodb version >2.6.0 to perform the needed aggregate queries. This is your mongo database version, not your node package version! To check your database version, connect to mongo and run db.version().

Middleware usage

Express

Agendash provides Express middleware you can use at a specified path, for example this will make Agendash available on your site at the /dash path. Note: Do not try to mount Agendash at the root level like app.use('/', Agendash(agenda)).

var express = require("express");
var app = express();

// ... your other express middleware like body-parser

var Agenda = require("agenda");
var Agendash = require("agendash");

var agenda = new Agenda({ db: { address: "mongodb://127.0.0.1/agendaDb" } });
// or provide your own mongo client:
// var agenda = new Agenda({mongo: myMongoClient})

app.use("/dash", Agendash(agenda));

// ... your other routes

// ... start your server

By mounting Agendash as middleware on a specific path, you may provide your own authentication for that path. For example if you have an authenticated session using passport, you can protect the dashboard path like this:

app.use(
  "/dash",
  function (req, res, next) {
    if (!req.user || !req.user.is_admin) {
      res.send(401);
    } else {
      next();
    }
  },
  Agendash(agenda)
);

Other middlewares will come soon in the folder /lib/middlewares/. You'll just have to update the last line to require the middleware you need:

app.use(
  "/agendash",
  Agendash(agenda, {
    middleware: "connect",
  })
);

Note that if you use a CSRF protection middleware like csurf, you might need to configure it off for Agendash-routes.

Hapi

A minimum Node.js version 12 is required for @hapi/hapi dependency.

npm i @hapi/inert @hapi/hapi
const agenda = new Agenda().database(
  "mongodb://127.0.0.1/agendaDb",
  "agendaJobs"
);

const server = require("@hapi/hapi").server({
  port: 3002,
  host: "localhost",
});
await server.register(require("@hapi/inert"));
await server.register(
  Agendash(agenda, {
    middleware: "hapi",
  })
);

await server.start();

Then browse to http://localhost:3002/.

Koa

npm i koa koa-bodyparser koa-router koa-static
const agenda = new Agenda().database(
  "mongodb://127.0.0.1/agendaDb",
  "agendaJobs"
);

const Koa = require("koa");
const app = new Koa();
const middlewares = Agendash(agenda, {
  middleware: "koa",
});
for (const middleware of middlewares) {
  app.use(middleware);
}

await app.listen(3002);

Then browse to http://localhost:3002/.

Fastify

npm i fastify
const agenda = new Agenda().database(
  "mongodb://127.0.0.1/agendaDb",
  "agendaJobs"
);

const Fastify = require("fastify");
const fastify = new Fastify();

fastify.register(
  Agendash(
    agenda, 
    { middleware: "fastify" }
  );
);

await fastify.listen(3002);

Then browse to http://localhost:3002/.

Standalone usage

Agendash comes with a standalone Express app which you can use like this:

./node_modules/.bin/agendash --db=mongodb://localhost/agendaDb --collection=agendaCollection --port=3002

or like this, for default collection agendaJobs and default port 3000:

./node_modules/.bin/agendash --db=mongodb://localhost/agendaDb

If you are using npm >= 5.2, then you can use npx:

npx agendash --db=mongodb://localhost/agendaDb --collection=agendaCollection --port=3002

Then browse to http://localhost:3002/.

Docker usage

Agendash can also be run within a Docker container like this:

docker run -p 3000:3000 \
  --env MONGODB_URI=mongo://myUser:myPass@myHost/myDb \
  --env COLLECTION=myAgendaCollection agenda/agendash

Then browse to http://localhost:3000/.

agendash's People

Contributors

art-grig avatar bh-chaker avatar dependabot[bot] avatar ebourmalo avatar enubia avatar hugocornu avatar jframbach-nerdwallet avatar joeframbach avatar koresar avatar lgaticaq avatar ljacho avatar love8587 avatar luislobo avatar nico-code avatar nicolaselopez avatar omgimalexis avatar pavel-lens avatar pirifle avatar r0binxp avatar rapidia avatar renovate-bot avatar renovate[bot] avatar rluvaton avatar santiq avatar simison avatar simllll avatar ssl37 avatar umens avatar vziukas avatar wolfulus 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

agendash's Issues

Show some unique column for jobs

It would be great to add possibility to show some unique column in list.
I have the situation where are many jobs with the same name.
Filter by name is really cool, but when I have > 10 items in list it does not solve the problem.

For example I have to find job for specific user with specific email
I can review all jobs one by one until I will find needed job, but's it really boring and not useful.

I am not very familiar with Backbone, but willing to help if possible with anything
I think this issue will be as discussion first

No UI elements to create a new job

I use agandash as middleware and no UI-elements seen to create a new job.

in package.json stated:
"agenda": ">=0.7.0 <1.0.0",
could this be an issue? my app uses agenda-1.0.0

Koa2 support

Hi everyone, I found Agendash is easy to use, but missing the support for koa. And I notice that there exists a PR about supporting koa, but it seems too old to merge. So I create a new PR #84 , using koa2(^2.4.1), add some test and examples.

Here is what I did:

  1. Support koa2.
  2. Using async/await grammar for this feature. Cause after koa 2.4 version, we have to support async/await in native. And as this is a new feature, I think it's reasonable to do that,
  3. Rename test.js to express.test.js, add test folder and koa.test.js
  4. Add koa example in examples folder
  5. Change README

serve UI from a nested path and prevent redirect

Hey,

Great work on agendash it's looking nice.

I'm serving mine up from a nested path e.g. '/a/long/route/agendash'. However, it's automatically then redirecting back to '/agendash' which obviously can't be found.

My middleware init looks like this:

app.use('/agendash', Agendash(agenda));

Any quick ideas how I could fix this? I haven't dug through the code yet but may well raise a PR if I find a quick solution.

Thanks again!
Hugh

I cant configure as a middleware

I've follow the steps as the doc and I get

TypeError: agenda._mdb.admin is not a function
    at module.exports.<anonymous> (C:\Users\LautaroAgustin\Documents\GitHub\boliches-be\node_modules\agendash\lib\agendash.js:16:17)
    at emitNone (events.js:106:13)
    at module.exports.emit (events.js:208:7)
    at handleLegacyCreateIndex (C:\Users\LautaroAgustin\Documents\GitHub\boliches-be\node_modules\agenda\lib\agenda.js:128:10)

Env

mongoose 4.5.7
mongdb (package version) 2.2.29
mongodb (db version db.version()) 3.4.7
agenda 0.9.1
agendash 0.4.0

Clean up old worker data

So we have had workers run a while ago and we would like to clear up data on our MongoDB storage with worker data that is say over a month.

Dynamic page name (title)

How difficult to show queue name (or custom passed name) on top of page ?
This is for case when Agendash used to show jobs from multiple collections.

What is "queued" status?

I'm wondering what this "queued" status means.

Our app often gets put into this state:
screen shot 2017-10-19 at 9 39 47 am

As you can see, some jobs end up going into "queued" status and the "Next Run At" attribute gets set to some time in the past. Which will make the job never run again. It just sits there doing nothing. I'm also wondering why the Next Run At attribute is being shown as a past value, but that may be a question for node-agenda?

If we restart the server then all the jobs unlock and the "queued" status is changed to "scheduled"

Time does not update

Backbone will only rerender a view when the model has actually changed. The model contains: {name: ..., lastRunAt: ..., etc}. A job that hasn't updated in several minutes may still show "last run a minute ago" because the model hasn't updated and the time string hasn't rerendered.

Potential solutions:

  1. Write a setInterval which rerenders the time strings, like the jquery timeago plugin does referenced in #1
  2. Have backbone rerender the views regardless of if the model has actually changed

Wire up UI for "limit" and "skip" values

Hi,

Agendash works pretty well with my setup, only concern is the fact that there is no paging, and since we have like 20,000 jobs in the database the first load is very long...

Is it planned to add paging or some options to only get the first x jobs ?

Replace "in a few seconds" with more accurate time

Agendash currently uses e.g., moment(1458000000000).fromNow() to display the time difference for last execution and next execution. When a job is within 45 seconds of executing, moment will display in a few seconds which is not very helpful and is not very configurable.

Replace moment.fromNow with something better.

Application crash when requeue in dashboard

When I press the Requeue selected application crash with below error logs:


..../node_modules/mongodb/lib/utils.js:132
      throw err;
      ^

Error: This function does not accept a callback function. 1/0
    at module.exports (.../node_modules/agenda/lib/no-callback.js:12:11)
    at Job.module.exports [as save] (..../node_modules/agenda/lib/job/save.js:12:3)
    at .../node_modules/agendash/lib/agendash.js:65:12
    at .../node_modules/agendash/node_modules/async/lib/async.js:718:13
    at iterate (.../node_modules/agendash/node_modules/async/lib/async.js:262:13)
    at async.forEachOfSeries.async.eachOfSeries (.../node_modules/agendash/node_modules/async/lib/async.js:281:9)
    at _parallel (/.../node_modules/agendash/node_modules/async/lib/async.js:717:9)
    at Object.async.series (/.../node_modules/agendash/node_modules/async/lib/async.js:739:9)
    at /.../node_modules/agendash/lib/agendash.js:63:15
    at result (.../node_modules/mongodb/lib/utils.js:414:17)
    at executeCallback (.../node_modules/mongodb/lib/utils.js:406:9)
    at handleCallback (.../node_modules/mongodb/lib/utils.js:128:55)
    at cursor.close (.../node_modules/mongodb/lib/operations/cursor_ops.js:216:62)
    at handleCallback (.../node_modules/mongodb/lib/utils.js:128:55)
    at completeClose (/.../node_modules/mongodb/lib/cursor.js:893:14)
    at _endSession (/.../node_modules/mongodb/lib/cursor.js:904:37)
    at Cursor._endSession (.../node_modules/mongodb-core/lib/cursor.js:194:5)
    at Cursor._endSession (.../node_modules/mongodb/lib/cursor.js:226:59)
    at Cursor.close (/.../node_modules/mongodb/lib/cursor.js:904:19)
    at cursor._next (..../node_modules/mongodb/lib/operations/cursor_ops.js:216:23)
    at handleCallback (..../node_modules/mongodb-core/lib/cursor.js:203:5)
    at _setCursorNotifiedImpl (.../node_modules/mongodb-core/lib/cursor.js:561:38)
    at self._endSession (/.../node_modules/mongodb-core/lib/cursor.js:569:46)
    at ClientSession.endSession (/.../node_modules/mongodb-core/lib/sessions.js:129:41)
    at Cursor._endSession (/.../node_modules/mongodb-core/lib/cursor.js:189:13)
    at Cursor._endSession (.../node_modules/mongodb/lib/cursor.js:226:59)
    at _setCursorNotifiedImpl (.../node_modules/mongodb-core/lib/cursor.js:569:17)

Use it as logged in user

I'm trying it with:

    app.use('/jobs', function(req, res, next) {
	if (req.user) return agendash(agenda);
	next();
    });

But it returns a 404, any ideas?

Configure Web

What is Schedule ,Repeat every and job data (json)?
How to configure? What is the format?

failed vs. completed

I'm seeing this behavior where a job will sometimes show up as "failed" and othertimes show up as "completed" (even though it has both failedAt and failedReason values)

I realized what caused this difference:

agenda.define('...', (job, done) => {
   // this job will show up in the "completed" bucket
   done('Something went wrong')
})
agenda.define('...', (job, done) => {
   // this job will show up in the "failed" bucket
   job.fail('Something went wrong')
})

In the above 2 examples both jobs appear to have the same attributes:

image 2017-06-13 at 5 07 40 pm

There's a couple things I can't figure out -

  • How does Agendash determine if the job is "failed" or "completed" if the attributes of the job look exactly the same? (I tried to find this difference in the source, but I couldn't quite figure it out)
  • Even though both these jobs have "nextRunAt" times that are in the past, they are not be run again, this might be more of an issue with agenda or how I'm using agenda, but maybe it is related.

Thanks!

Connect to remote Atlas Cluster?

I have an agenda app that is currently using an atlas mongodb instance, and is running jobs successfully.

When I try to start agendash, connecting to the same atlas instance, with the following connection command

./node_modules/.bin/agendash --db=mongodb:username:pw@<instance1>rpnad.mongodb.net:27017,<instance2>rpnad.mongodb.net:27017,<instance3>rpnad.mongodb.net:27017/agenda?replicaSet=JP-Appointment-Scheduler-shard-0&retryWrites=true collection=agendaCollection

I get the following error.

.../node_modules/agendash/node_modules/mongodb/lib/mongo_client.js:421
          throw err
          ^
Error: read ECONNRESET
    at _errnoException (util.js:1022:11)
    at TCP.onread (net.js:628:25)

Any examples of using an Atlas hosted Mongo Instance with Agendash?

Cannot schedule job when used inside express

Hello,
When using agenda-dash inside express, the UI showed up, but cannot schedule job. After click "Save" nothing happen.
If running agenda-dash standalone, everything works fine

Agendash init issue

Hi,

I'm trying to use Agendash according to documentation, but I get the following error while trying to use the middleware option:

[SyntaxError: C:\Develop\LimitlessDev\seScheduler\node_modules\agendash\lib\agendash.js:42
.find({_id: {$in: jobIds.map((jobId) => new ObjectId(jobId))}})
^^
Unexpected token =>]

I use loopback as framework.
Agenda is running well.
Any idea what might be the ussue?

Thank you and regards,
Elrom

Delete and Requeue buttons do not work anymore

Agendash thows Cannot read property 'pkFactory' of undefined in this line:

agenda.cancel({_id: {$in: jobIds.map((jobId) => agenda._collection.s.pkFactory(jobId))}}, function (err, deleted) {

Look like with latest agenda it should be agenda._collection.collection.s.pkFactory instead.

Please update the NPM package

The mongo version error is fixed in the latest commits, please update the npm package so everyone could access it easily.

Enhancement: Job Meta Info with Iconography

Firstly - Thanks.. this was handy.
I would really like

  • a better UI grid - this seems a relatively trivial UI task.. Many frameworks to choose from.

  • New field Job Types represented by Icons (e.g. email, DB, Log Files, General, Affecting Users etc..)

  • Form needs validation and some info text around (also docs are missing)

  • Job Chaining (or grouping with sequencing within the group and exception handling job options). I come from an enterprise software background so some of these ideas come from there..

Thanks...

Jobs not showing up as failed

Even though there's a failReason and the job is set to disabled it doesn't show up as such in Agendash.

{ 
    "_id" : ObjectId("591801f43cc07a63b20feadf"), 
    "name" : "stats", 
    "url" : "staff", 
    "data" : {
        "_id" : ObjectId("591801f49dda0642e2564454"), 
        "url" : "staff"
    }, 
    "type" : "normal", 
    "priority" : NumberInt(10), 
    "nextRunAt" : ISODate("2017-05-14T07:06:38.483+0000"), 
    "repeatInterval" : "10 seconds", 
    "repeatTimezone" : null, 
    "lastModifiedBy" : null, 
    "lockedAt" : ISODate("2017-05-14T07:06:28.326+0000"), 
    "lastRunAt" : ISODate("2017-05-14T07:06:28.483+0000"), 
    "failReason" : "Blog was disconnected from Twistly.", 
    "failCount" : NumberInt(1), 
    "failedAt" : ISODate("2017-05-14T07:06:28.581+0000"), 
    "disabled" : true
}

screen shot 2017-05-14 at 4 42 18 pm

Reque for a scheduled job is failing.

I have an agenda task scehduled at some defined time. However, when i try to reque from agendash, the POST call "api/jobs/requeue" returns 404. Any solution for this?

Buttons not working

I've been using Agendash for a while and everything was working fine, but suddenly all buttons return 404 (Not Found) error.
On the console, I only see Error: Can't set headers after they are sent.

I'm not sure what changed when the error started, I suspect it has something to do with updating the NPM packages.

Move the API into it's own package

agenda-rest has just joined the Agenda org so we'll be looking into cleaning up the code to use ava and xo just like the other packages we maintain.

After this we should document which methods we currently serve up as an api so we can migrate them to Koa and integrate it all directly into agenda-rest.

PING: @agenda/maintainers
Ref: agenda/agenda-rest#3

Sort exceeded memory

Opening agendash doesn't work anymore, the api call returns the following error message:
"Sort exceeded memory limit of 104857600 bytes, but did not opt in to external sorting. Aborting operation. Pass allowDiskUse:true to opt in."

Do I need any additonal index on my agenda schemas or should I add allowDiskUse to this query?

regards
Simon

Schedule Job Feature

It would be great to have a Schedule Job feature.
It would be the GUI equivalent of a

agenda.schedule('in 20 minutes', 'send email report', {to: '[email protected]'});

I'm probably going to work on this if no-one else steps in before

SyntaxError: Unexpected token >

I am getting error : "SyntaxError: Unexpected token >".

Below is the full stack trace.

/home/wt/git/web/node_modules/agendash/lib/agendash.js:41
.find({_id: {$in: jobIds.map((jobId) => new ObjectId(jobId))}})
^
SyntaxError: Unexpected token >
at Module._compile (module.js:439:25)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at module.exports (/home/wt/git/web/node_modules/agendash/app.js:9:18)
at Object. (/home/wt/git/web/app1.js:15:22)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)

I am using node js 0.10.7

Taking a vacation for 5 months, need help

I am leaving in 3 weeks to hike the Pacific Crest Trail for 5 months. It is a long trip and I will not have reliable internet access at all. So I am asking for anyone willing to help maintain the issues/PRs for Agendash. @vziukas @ebourmalo @rapidia you all have commits on this project. Could you help to look at issues and PRs? I will add collaborators and npm publish access.

user input for both "Schedule" and "Repeat every"

I want to schedule a job to an exact time each day.
I am filling in both the "schedule" and "repeat every" inputs. E.g.

Schedule: 2018-06-28T13:00:00.000Z
Repeat Every: one day

Expected result:
Run the job at schedule time
Then repeat the job every day at that scheduled time.

Observed behavior:
The job starts running immediately
The job will be repeated every day at that time, disregarding scheduled time input.

Overall it seems when I fill in "repeat every" field, my input is ignored for the "Schedule".

buttons not working in mounted mode

i have mounted agendash to my own application -- it can render stuff all good but i can't reschedule jobs using them as the buttons are not working.

Jobs don't execute in order

Steps to reproduce:

[1,2,3,4,5,6,7,8,9].forEach(function (n) {
  agenda.create('doSomethingWithNumber', {
    n: n
  })
  .save()
})

The UI now shows 9 jobs "queued" since they are ready to run but haven't started yet.

The jobs will execute in a seemingly nondeterministic order.

Need to experiment to see if this is something I'm doing wrong or something Agenda is doing

Rescheduled job runs infinitelly

There is a job scheduled, the database record looks like this,

{
    "_id" : ObjectId("5a314abea4c8964c6bb818a7"),
    "name" : "fact-sync-application",
    "type" : "single",
    "data" : null,
    "priority" : 0,
    "nextRunAt" : ISODate("2017-12-14T17:00:00.277Z"),
    "repeatInterval" : "0 17 * * *",
    "repeatTimezone" : null,
    "lastModifiedBy" : null,
    "lockedAt" : null,
    "lastRunAt" : ISODate("2017-12-13T17:00:00.243Z"),
    "lastFinishedAt" : ISODate("2017-12-13T17:06:51.007Z")
}

From UI, I reschedule the job and new instance appear,

{
    "_id" : ObjectId("5a3257a021628330f8b59893"),
    "name" : "fact-sync-application",
    "data" : null,
    "type" : "normal",
    "priority" : 0,
    "nextRunAt" : null,
    "lastModifiedBy" : null,
    "lockedAt" : ISODate("2017-12-14T10:51:16.500Z"),
    "lastRunAt" : ISODate("2017-12-14T10:51:16.507Z")
}

It's a quite long running job, but what I see, once it's completed it immediately started again. What could be an explanation for that?

Also, I'm thinking what's the rationality behind "Reschedule" feature. What I typically want is to "Restart" the job manually from the UI. Looks like Agenda API allows that via .run() method.

Do you think this is something that can be added as a button for UI as well?

requeue doesn't work with new async / await

Now that Agenda has been updated to use async / await, I think it's time to also update Agendash. I'm getting the error "This function does not accept a callback function. 1/0" when trying to requeue a job in the Agendash UI.

The dot in the key name in Job data (JSON)

I tries create job with next data
{ "name": "stage facebook happy path", "webhook": "https://bot.ai", "channel": "facebook", "steps": [{ "text": "start over", "maxResponseTime": 20000, "response": { "currentState.name": "CONFIRM_COMMAND" } }] }

and got 404 response from API with the message "Jobs not created"

But if I change key "currentState.name" to "currentState_name" - all fine.
Looks like a problem in the dot.
This is reproduced with simple data like
{"name.name": "data"}

"agenda": "^1.0.3",
"agendash": "^0.4.0",

➜ project git:(development) ✗ mongod --version
db version v3.6.5
git version: a20ecd3e3a174162052ff99913bc2ca9a839d618
OpenSSL version: OpenSSL 1.0.2o 27 Mar 2018
allocator: system
modules: none
build environment:
distarch: x86_64
target_arch: x86_64

see job that isn't scheduled

Is there a way to see a job that has been defined or created in agenda but has not yet been scheduled to run?

Thanks

Jobs never fail

In the job definition I write

          if (error){
            job.fail(error.message)
            console.log(error)
            return job.save(function(err) {
              done();
            })
          } else {
            done();
          }

The job get a field failReason but Agendash doesn't show the job as failed.

How do I ensure that jobs will be marked as failed when they get an error

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.