Code Monkey home page Code Monkey logo

impress's Introduction

impress logo ci Status snyk npm downloads/month npm downloads license

Enterprise application server for Node.js: secure, lightweight, interactive, and scalable.

Description

First Node.js server scaled with multithreading and extra thin workload isolation. Optimized for high-intensive data exchange, rapid development, and clean architecture. Provides everything you need out of the box for reliable and efficient backend, network communication with web and mobile clients, protocol-agnostic API, run-time type validation, real-time and in-memory data processing, and reliable stateful services.

Weak sides: not a good choice for content publishing including blogs and online stores, server-side rendering, serving static content and stateless services.

Strong sides: security and architecture for enterprise-level applications, long-lived connections over websocket to minimize overhead for cryptographic handshake, no third-party dependencies.

Quick start

API endpoint example: application/api/example.1/citiesByCountry.js

async ({ countryId }) => {
  const fields = ['cityId', 'name'];
  const where = { countryId };
  const data = await db.select('City', fields, where);
  return { result: 'success', data };
};

You can call it from client-side:

const res = await metacom.api.example.citiesByCountry({ countryId: 3 });

Metarhia and impress application server way

  • Applied code needs to be simple and secure, so we use sandboxing with v8 isolated contexts, worker threads and javascript closures;
  • Domain code should be separated from system code; so we use DDD, layered (onion) architecture, DI, SOLID and GRASP principles, contract-based approach;
  • Impress supports stateful applications with RPC and client-session sticky to servers; microservices, centralized or distributed architecture;
  • No I/O is faster even than async I/O, so we hold state in memory, share it among multiple threads and use lazy I/O for persistent storage;
  • We use just internal trusted dependencies, no third-party npm packages; total Metarhia technology stack size is less than 2mb.

Features

  • API auto-routing calls to endpoint for rapid API development (no need to add routes manually)
  • API concurrency: request execution timeout and execution queue with both timeout and size limitations
  • Schemas for API contract, data structures validation, and domain models
  • Application server supports different API styles: RPC over AJAX and over Websocket, REST, and web hooks
  • Multiple protocols support: HTTP, HTTPS, WS, WSS
  • Auto loader with start hooks, namespace generation for code and dependencies
  • Live reload of code through filesystem watch
  • Graceful shutdown with stop hooks
  • Minimal dependencies and reduced code size
  • Layered architecture: api, domain logic, data access layer, and system code layer (hidden)
  • Code sandboxing for enhanced security and execution context isolation
  • Code protection: reference pollution prevention, prototype pollution prevention
  • Multi-threading for CPU utilization and execution isolation
  • Load balancing for simple scaling with redirection to multiple ports
  • Caching: in-memory caching for APIs and static files
  • Configuration: environment-specific application settings
  • Database access layer compatible with PostgreSQL with SQL-injection protection
  • Persistent sessions with authentication, groups, and anonymous sessions
  • Buffered logging (lazy write) with log rotation (keep logs N days) and console interface
  • Testing: integrated node.js native test runner and table-test support
  • Inter-process communication and shared memory used for state management
  • File utilities: upload, download, support for partial content and streaming
  • Task Management: scheduled task execution at specific intervals or certain times

TODO list

Those features will be implemented in nearest future (3-6 months):

  • Server health monitoring
  • Database migrations
  • State synchronization mechanism with transactions and subscription
  • Multi-tenancy support

Requirements

  • Node.js v18.x or v20.x
  • Linux (tested on Fedora v36-38, Ubuntu v18-23, CentOS v8-9)
  • Postgresql v11-16
  • OpenSSL v3 or later (optional, for https & wss)
  • certbot (recommended but optional)

License & Contributors

Copyright (c) 2012-2024 Metarhia contributors. See github for full contributors list. Impress Application Server is MIT licensed. Project coordinator: <[email protected]>

impress's People

Contributors

aqrln avatar belochub avatar dehimer avatar dependabot[bot] avatar dzyubspirit avatar georgolden avatar imnetcat avatar ivan-tymoshenko avatar j-martyn avatar jekrock avatar johnbizokk avatar juliagerasymenko avatar klarpen avatar lundibundi avatar mille-nium avatar nazar32 avatar nechaido avatar nikitavbv avatar o-rumiantsev avatar primeare avatar semenchenkovitaliy avatar sensarg22 avatar slavakaderkin avatar streetstrider avatar tblasv avatar theelix avatar timursevimli avatar tshemsedinov avatar vara855 avatar viktor-evdokimov avatar

Stargazers

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

Watchers

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

impress's Issues

Strange encoding of client.fields when accessing from api.

I'm trying to get POST data from client.fields property and getting such string which cannot be parsed with JSON.parse:
{ '{"0":{"value":"alega","path":"services.list.1.0.header"},"1":{"value":"agafonov ': '',
'nbsp;","path":"services.list.1.1.header"}}': '' }
while client.data of the same post gives: {"0":{"value":"alega","path":"services.list.1.0.header"},"1":{"value":"agafonov  ","path":"services.list.1.1.header"}}
which is ok for the parser.

падение при неверном доменном имени

допустим я у себя в hosts делаю запись
127.0.0.1 xn--127-qdd4dec.xn--p1ai
и захожу браузером соответственно на http://тест127.рф/
в applications/example/config/hosts.js остается как и было
module.exports = [
"127.0.0.1"
]
тогда сервер падает с таким сообщением

2014-01-29T21:54:19.252Z Master(7484/C1N0) TypeError: Cannot read property 'cache' of undefined; Client.include (\node_modules\impress\lib\impress.js:1037:23); Client.error (\node_modules\impress\lib\impress.js:898:9); Server.impress.dispatcher (\node_modules\impress\lib\impress.js:579:29); Server.EventEmitter.emit (events.js:98:17); HTTPParser.parser.onIncoming (http.js:2108:12); HTTPParser.parserOnHeadersComplete as onHeadersComplete; Socket.socket.ondata (http.js:1966:22); TCP.onread (net.js:525:27)

если конечно в applications/example/config/hosts.js сделать
module.exports = ["*"]
то работает и http://127.0.0.1/ и http://тест127.рф/
я так понимаю, что на левый домен страница с ошибкой все таки должна вылезать...

Create visual setup

Create visual setup for optional modules, plugings and configuration parameters.

[q] Url regexp routing

Let's imagine that I need urls like: http://example.com/<username>/profile which will point to folder profile and use get.js or post.js inside that folder and pass <username> as query string param or as a part of form data.
Can this framework do something like this?

Improve performance of Client

We can change mixin to class factory, to prepare special class for each application on server start or on config change and mixin additional methods to this class prototype but not to Client instances. This will increase performance I believe, but testing needed.

странные попытки найти конфигурацию от корня диска в винде

вот я ковыряю импресс под виндой в каталоге C:\data\node\ws
соответственно ваш пример в C:\data\node\ws\applications\example
и конфиг в C:\data\node\ws\config
запустил из под отладчика вебшторма и увидел вот такие попытки найти конфиги в корне диска, но при этом однако все работает.... как то странно...

"C:\Program Files\nodejs\node.exe" --debug-brk=51320 server.js
debugger listening on port 51320
Impress Application Server starting, reading configuration
{ [Error: ENOENT, no such file or directory 'C:\config\cloud.js']
errno: 34,
code: 'ENOENT',
path: 'C:\config\cloud.js',
syscall: 'open' }
Startup check: http://127.0.0.1/
{ [Error: ENOENT, no such file or directory 'C:\config\cluster.js']
errno: 34,
code: 'ENOENT',
path: 'C:\config\cluster.js',
syscall: 'open' }
listen on 127.0.0.1:80
{ [Error: ENOENT, no such file or directory 'C:\config\log.js']
errno: 34,
code: 'ENOENT',
path: 'C:\config\log.js',
syscall: 'open' }
{ [Error: ENOENT, no such file or directory 'C:\config\plugins.js']
errno: 34,
code: 'ENOENT',
path: 'C:\config\plugins.js',
syscall: 'open' }
{ [Error: ENOENT, no such file or directory 'C:\config\servers.js']
errno: 34,
code: 'ENOENT',
path: 'C:\config\servers.js',
syscall: 'open' }
{ [Error: ENOENT, no such file or directory 'C:\config\sandbox.js']
errno: 34,
code: 'ENOENT',
path: 'C:\config\sandbox.js',
syscall: 'open' }
{ [Error: ENOENT, no such file or directory 'C:\example\config\databases.js']
errno: 34,
code: 'ENOENT',
path: 'C:\example\config\databases.js',
syscall: 'open' }
{ [Error: ENOENT, no such file or directory 'C:\example\config\application.js']
errno: 34,
code: 'ENOENT',
path: 'C:\example\config\application.js',
syscall: 'open' }
{ [Error: ENOENT, no such file or directory 'C:\example\config\example.js']
errno: 34,
code: 'ENOENT',
path: 'C:\example\config\example.js',
syscall: 'open' }
{ [Error: ENOENT, no such file or directory 'C:\example\config\files.js']
errno: 34,
code: 'ENOENT',
path: 'C:\example\config\files.js',
syscall: 'open' }
{ [Error: ENOENT, no such file or directory 'C:\example\config\hosts.js']
errno: 34,
code: 'ENOENT',
path: 'C:\example\config\hosts.js',
syscall: 'open' }
{ [Error: ENOENT, no such file or directory 'C:\example\config\mail.js']
errno: 34,
code: 'ENOENT',
path: 'C:\example\config\mail.js',
syscall: 'open' }
{ [Error: ENOENT, no such file or directory 'C:\example\config\routes.js']
errno: 34,
code: 'ENOENT',
path: 'C:\example\config\routes.js',
syscall: 'open' }
{ [Error: ENOENT, no such file or directory 'C:\example\config\sessions.js']
errno: 34,
code: 'ENOENT',
path: 'C:\example\config\sessions.js',
syscall: 'open' }

теряется соединение с БД

имеем приложение impress, базы mongodb и mysql
impress запущен через forever
после запуска работает нормально весь день (процесс разработки и отладки приложения), остается работающим на серверt и на следующий день начинаются проблемы - в обозреватель загружаются только статические файла (то, что в files.js).
запросы api не выполняются.

после рестарта - все работает

кусочки конфига:
cloud.js:
controller: "192.168.3.100",

cluster.js:
check: "http://192.168.3.100/"
strategy: "sticky",

plugins.js:
"db",
//"db.schema",
"db.mongodb",
//"db.memcached",
"db.mysql",
//"db.mysql.schema",
"impress.log",
"impress.security",
"impress.security.mongodb",
//"impress.mail",
"impress.uglify",
//"impress.health",
//"impress.cloud",
//"impress.geoip",
//"impress.websocket",
"impress.sse"

servers.js:
protocol: "http",
address: "192.168.3.100",
port: 80,
applications: ["agat", "iserv"],
nagle: true,
slowTime: "1s"

databases.js:
impress: {
url: "mongodb://localhost:27017/impress",
slowTime: "2s",
collections: ["sessions", "users", "groups"],
security: true
},
system: {
url: "mysql://root:123456789@localhost/agat",
slowTime: 1000,
tables: []
}

логи:
access.log - всегда отображаются все входящие запросы
debug.log - отображаются sql запросы, после появления ошибки - ничего не фиксируется

error.log:
2014-03-12T21:19:24.891Z Master(6242/C1N0) {"fatal":true,"code":"PROTOCOL_CONNECTION_LOST"}
2014-03-12T21:19:24.891Z Worker(6251/C1N3) {"fatal":true,"code":"PROTOCOL_CONNECTION_LOST"}
2014-03-12T21:19:24.893Z Worker(6249/C1N2) {"fatal":true,"code":"PROTOCOL_CONNECTION_LOST"}
2014-03-12T21:19:59.889Z Worker(6248/C1N1) {"fatal":true,"code":"PROTOCOL_CONNECTION_LOST"}

может быть, коннект отваливается по тайм-ауту при простое и при появлении новых запросов не поднимается...?

timezone && mysql

в качестве БД - mysql, сервер sles 11
для mysql и системы указана правильная временная зона
запросы к mysql из консоли (mysql) и MySQL Workbench возвращают правильные даты (тип datetime)

запросы из impress возвращают даты приведенные к UTC (на 4 часа меньше)
в результате получаются даты и неверным днем (это зависит от времени - если время = 00:00, вычитается 4 часа и получается вчерашний день)

в Node пока чайник, в результате поисков нашлось вот это:
process.env.TZ = 'Europe/Moscow';

прописал в один из обработчиков, но изменений нет

что нужно сделать, чтобы получать даты из запросов к mysql в соответствии с временной зоной?

Impress on linux on 80 port.

If you run impress that configured to listen on 80 port from non-root (non-privileged) user it will say that application is started successfully and is listening on 80 port. And logs will be empty.
But on linux non-root users can't open ports below 1024 for listening. So as a result application says that's all ok and it's runnning, but actually it can't listen on 80 port, so if I open i.e. http://127.0.0.1/ browser will show an error.

May be it will be better if impress somehow check if it actually can open that port, or at least show some warning about possible problems with ports below 1024.

hmenu.everyone.template не отображается в примере

Зарегистрировался, вхожу с использованием формы логина. Ничего не происходит. Верхнее меню не меняется. В базе mongodb/impress пользователь зарегистрировался. Сессия есть.

Separate applications

  1. Load separate config files for each application
  2. Load each application in sandbox
  3. Separate database access for different applications

How to create custom impress plugins (modules)?

I've installed example and it has only sites folder and config.js, server.js, setup.js. Now I need to create custom module (plugin) or override existing. I've tried one way: cloned impress from git, added test plugin into it and then configured my project to use impress from local git, not from npm. And this way worked. Is this right way to add custom modules to impress or may-be there is another way to do it?

Sticky

Try to fix IP "sticky" serving strategy on windows or disable this strategy with warning and fall-back to "multiple" strategy if it is impossible.

Add new parameters to sessions.js

  1. perIpLimit - Maximum session count to be created for one IP address
  2. confirmTime - Expiration timeout after which session will live but password confirmation needed
  3. expireTime - Expiration timeout after which session will be deleted
  4. perUserLimit - Maximum session count to be created for one user account

Пожелание: Добавьте примеров и документацию

Пример, который идет в комплекте довольно сложный. Было бы неплохо, если бы были более простые примеры типа Hello World.

А документация на конфиги и основные модули была бы просто незаменима.

Remove .existsSync

Replace .existsSync to asynchronous analogs in API introspection implementation, see impress.js, lines: 1001, 1003

server starting problem on Mac

Fixed. Sory port 80 problem.


I start a server on mac os x 10.8.4.

And resive folowind errors:
TypeError: Cannot read property 'getsockname' of undefined
at net.js:1055:23
at Object.32:1 (cluster.js:587:5)
at handleResponse (cluster.js:171:41)
at respond (cluster.js:192:5)
at handleMessage (cluster.js:202:5)
at process.EventEmitter.emit (events.js:117:20)
at handleMessage (child_process.js:318:10)
at Pipe.channel.onread (child_process.js:345:11)
net.js:1055
if (port && handle.getsockname && port != handle.getsockname().port) {
^
TypeError: Cannot read property 'getsockname' of undefined
at net.js:1055:23
at Object.31:1 (cluster.js:587:5)
at handleResponse (cluster.js:171:41)
at respond (cluster.js:192:5)
at handleMessage (cluster.js:202:5)
at process.EventEmitter.emit (events.js:117:20)
at handleMessage (child_process.js:318:10)
at Pipe.channel.onread (child_process.js:345:11)

And so on.

On windows (same notebook) works good.

Detect no callback in handler

If handler (get.js, post.js, request.js, etc.) will not call function callback within timeout we should detect it, terminate connection and reply with error message.

Implement task scheduling

Scheduling for applications: single process, multiple processes on single server (cluster), multiple processes on multiple servers (cloud). No duplicate execution in multiple instances but with guaranted execution and restarting on fails.

Implement rewriting without regex expression (for example: (.*) on line end)

When we have
"routes": {
"Test1": {
"url": "/Test-0/GetPersons",
"rewrite": "/api/Test/GetPersons",
"host": "10.13.125.167",
"port": 81
}
}

//Test1 /Test-0/GetPersons(.) /api/Test/GetPersons 10.13.125.167 81
the rewrite engine not accept url, but when we change "url" option to "url": "/Test-0/GetPersons(.
)" then all works fine.

Can you implement simple syntax when we not need (.*) at end of url.

I can not run

F:\Impress>node server
Startup check: http://127.0.0.1/
Impress Application Server starting, reading configuration
listen on 127.0.0.1:80

events.js:72
throw er; // Unhandled 'error' event
^
Error: spawn ENOENT
at errnoException (child_process.js:980:11)
at Process.ChildProcess._handle.onexit (child_process.js:771:34)

F:\Impress>node -v
v0.10.18

включение, выключение сайтов в конфигах

допустим я создаю в /applications каталог test
в /config/servers.js остается
applications: ["example"]

тем не менее impress при запуске этот test сразу грузит:
C:\data\node\ws>node server.js
�[32m�[1mImpress Application Server starting�[22m�[39m�[32m, reading configuration�[39m
open C:/data/node/ws/config/cloud.js
open C:/data/node/ws/config/cluster.js
open C:/data/node/ws/config/log.js
open C:/data/node/ws/config/plugins.js
open C:/data/node/ws/config/sandbox.js
open C:/data/node/ws/config/servers.js
�[32mStartup check: �[39mhttp://127.0.0.1/
listen on 127.0.0.1:80
open C:/data/node/ws/log/2014-01-30-access.log
open C:/data/node/ws/log/2014-01-30-error.log
open C:/data/node/ws/log/2014-01-30-debug.log
open C:/data/node/ws/log/2014-01-30-slow.log
open C:/data/node/ws/applications/example/config/application.js
open C:/data/node/ws/applications/example/config/databases.js
open C:/data/node/ws/applications/example/config/example.js
open C:/data/node/ws/applications/example/config/files.js
open C:/data/node/ws/applications/example/config/hosts.js
open C:/data/node/ws/applications/example/config/mail.js
open C:/data/node/ws/applications/example/config/routes.js
open C:/data/node/ws/applications/example/config/sessions.js
open C:/data/node/ws/applications/test/config/application.js
open C:/data/node/ws/applications/test/config/databases.js
open C:/data/node/ws/applications/test/config/files.js
open C:/data/node/ws/applications/test/config/hms.js
open C:/data/node/ws/applications/test/config/hosts.js
open C:/data/node/ws/applications/test/config/mail.js
open C:/data/node/ws/applications/test/config/routes.js
open C:/data/node/ws/applications/test/config/sessions.js

а если каталог test пустой падает:
2014-01-30T09:04:24.203Z Master(8804/C1N0) TypeError: Object.keys called on non-object; Function.keys (native); \node_modules\impress\lib\impress.js:154:26; ReaddirReq.Req.done (\node_modules\impress\node_modules\npm\node_modules\graceful-fs\graceful-fs.js:143:5); ReaddirReq.done (\node_modules\impress\node_modules\npm\node_modules\graceful-fs\graceful-fs.js:90:22); Object.oncomplete (fs.js:107:15)

Separate log files for applications

Separate log files for applications as optional feature. Allow to choice (for each application):

  • Global logging only
  • Global and separated logs
  • Separated logs only

Security problem: serving access.js as static file

In static folders or if access.js matched static regexp Impress serving is as a static file. This file includes no critical security information except flags and group names but should be fixed because we may want to hold real static code in /js/access.js to be executed at client side, so we have name overlapping.

Autorun

  • Start automatically during the system startup.
  • Become a service to be controlled from command line: service impress start|stop|restart|status.
  • Restart on errors is already implemented in following instantiation modes: "cluster", "multiple" and "specialization".

Cluster strategy "specialization"

Now implemented this way: multiple processes, one master and different workers for each server (master should not listen ports). On port 80 it works well, but on other ports session cookie "SID" and process identifier "node" cookie not works.

Cache memory limits

Implement cache memory limits with serving statistics to release less used resources.

Separate sandbox configuration

Now there is one sandbox configuration for all applications. We need to have separate configurations for each application with different access to namespaces.

Refactor all plugins to new conventions

New conventions:

  1. pluginName.mixinApplication(application),
  2. application.pluginName.mixinClient(client),
  3. client.pluginName.init(callbackSuccess, callbackFail) or (err, callback)

Template by group name problem

Detected problem: it seems that virtual group "everyone" is not applied for user if one have other group but we have no appropriate template for his group, in this case "everyone" template should be used but it does not.

Fix Linux service "update" and "restart" behavior

Commands "service impress update" and "service impress restart" now starts impress after update and after stop respectively, but this behavior is wrong, service/daemon state should become the same as it was before command execution.

падение при включенной mongodb

при включении в /config/plugins.js
"db.mongodb"
после запуска падает:

Impress Application Server starting, reading configuration
Exception in master process
TypeError: Cannot set property 'mongodb' of undefined
at global.db (/node_modules/impress/lib/db.mongodb.js:7:22)
at Object. (/node_modules/impress/lib/db.mongodb.js:43:3)
at Module._compile (module.js:456:26)
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 loadPlugins (/node_modules/impress/lib/impress.js:227:17)
at /node_modules/impress/lib/impress.js:276:4
Impress shutting down

Extend Impress.health functionality

Consolidate and aggregate health data transmitting from workers to cluster and from cluster to Impress Cloud Controller. Create visualization interface for online and offline monitoring.

Add websocket support

It would be great if impress will support websokets.

And if you're planning to add it will it be your own implementation or you'll use something like socket.io or sockjs?
If you choose last may be you'll be interested in this library https://github.com/primus/primus. It acts like wrapper on many existing nodejs websocket implementations and allows easilly switch backends (like socket.io, engine.io and others) without rewriting your code.

Write line/pos of SyntaxError to log files

Example log file now, when SyntaxError occurs in handler(request.js, get/post.js, etc.): 2014-06-16T13:51:17.136Z Master(11260/C1N0) SyntaxError: Unexpected token :; new Script (vm.js:32:12); Function.Script.createScript (vm.js:48:10); impress.js:116:27; fs.js:266:14; Object.oncomplete (fs.js:107:15)

Fork long workers error

Fork works only from master thread, bur raise exception on worker threads:
worker AssertionError: false == true; Cluster.cluster.fork (cluster.js:505:3); Client.fork (\lib\impress.js:677:32);
Solution: call master thread by IPC and fork from master.

Implement self-testing mode

We need self-testing mode, so Application Server should run with special configuration key and execute internal testing for all functionality, log results and detect problems.

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.