CUBEJS: EBAY’S NODE.JS ADOPTION JOURNEY @
May 17, 2015
CUBEJS:EBAY’S NODE.JS ADOPTION JOURNEY
@
Patrick Steele-Idem
@psteeleidem
github.com/patrick-steele-idem
Senior Platform Architect @
EBAY HAS EMBRACED NODE.JS…SO HOW DID WE GET HERE?
BEFORE NODE.JS, JAVA WAS KING
BUT THINGS EVOLVED…
XML + XSLT JAVAPROPRIETARY OPEN SOURCEONE LANGUAGE POLYGLOTONE IDE ANY EDITOR/IDE
HEAVY FRONT-END LIGHTWEIGHT FRONT-ENDCLEARCASE GIT + GITHUB
SLOW DEVELOPMENT RAPID DEVELOPMENTJAVA APIS SERVICE APIS
“A DECLARATIVE, DATA-RETRIEVAL AND AGGREGATION GATEWAY FOR QUICKLY
CONSUMING HTTP APIS”…BUILT USING NODE.JS
WHY NODE.JS?• Non-blocking I/O
• Single-threaded
NODE.JS IS GREAT, BUT CAN EBAY USE IT TO
BUILD FRONT-ENDS AS WELL?
WHY NODE.JS FOR THE FRONT-END?DEVELOPER AGILITY, SCALABILITY
AND PERFORMANCE
“My advice: always bet on JavaScript”–Brendan Eich
WHAT IS REQUIRED TO SUPPORTNODE.JS AT EBAY?
MonitoringEncryption/Decryption
Resource Optimization
Tracking
Deployment
Look & Feel
Security
CSRF
Authentication
Personalization
Tools
Testing
Release Process
ConfigurationREST
SOAP
I18n
Logging App MetadataScalability
POLYGLOT CHALLENGE:HUGE INVESTMENT IN JAVA CODE
Possible Solutions Pros Cons
Port code to JavaScript
• Works for Node.js• Easy to debug
• Tedious• Error prone• What about Python, Ruby,
etc.?
Expose as a service • Polyglot friendly • Latency• Monitoring• Network Failures• Infrastructure
Port code to C/C++ • Fast• Bindings available
• Difficult to debug• Difficult to maintain
JVM ↔ JavaScript Bridge
• Polyglot friendly • Difficult to debug• Slower startup• Monitoring multiple VMs
1ST CHOICE: EXPOSE AS A SERVICEMAXIMIZE CODE REUSE
CALLS CAN BE MADE IN PARALLEL
2ND CHOICE: PORT CODE TO JAVASCRIPTPERFORMANCE CRITICALBEST HANDLED LOCALLY
DistributedLogging
ResourceServer
Application Layer Infrastructure Layer
Tracking
…
Client Layer
RUNTIME ARCHITECTURE
App Service Layer
Search
…
clus
ter2
DEVELOPMENT AND DEPLOYMENT INFRASTRUCTURE
an initiativeModule Packages
Private npm
Public npm
Source Code
Startup scripts
npm-delegate
powered by:
DESIGN GOAL:MAXIMIZE DEVELOPER PRODUCTIVITY
DESIGN GOAL: MAXIMIZE DEVELOPER PRODUCTIVITY
Small, bite-sized and easy-to-digest modules
Keep the documentation with the code.README files for the win
Encourage contributions
DESIGN GOAL: MAXIMIZE DEVELOPER PRODUCTIVITY
Avoid “magic”If developers cannot reason about a system
then they will not be happy or productive.
Do not be a restrictive frameworkDevelopers love options and being able to
use the latest and greatest.
DESIGN GOAL: MAXIMIZE DEVELOPER PRODUCTIVITY
+ File Watching+ Hot Reloading+ Web Sockets
Live CodingInstant Gratification
Web Development is Fun Again
CHECKOUT:• hot-reload https://github.com/philidem/node-hot-reload• socket.io http://socket.io/
NO BUILD STEP FOR RESOURCE OPTIMIZATION!
DESIGN GOAL: MAXIMIZE DEVELOPER PRODUCTIVITY
MORE INFO:• RaptorJS Optimizer: http://raptorjs.org/optimizer/
Resource bundling, minification, compilation, externalization—all at runtime.
Compile Raptor Templates, LESS, Dust, CoffeeScript, etc.
Command Line ToolsPowered by Rápido
DESIGN GOAL: MAXIMIZE DEVELOPER PRODUCTIVITY
CHECKOUT:Rápido: https://github.com/raptorjs/rapido
Features• Module and application lifecycle• Scaffolding• IDE/editor independence• PaaS integration• Jenkins CI integration• Command-line auto-completion• Colorized output
Example:ecube create appecube create pageecube registerecube create poolecube publishecube deploy
DESIGN GOAL:HIGH PERFORMANCE
PERFORMANCE IS GREAT*• Node.js provides a very low-level programming platform
• V8 is a powerful and fast JavaScript engine
• Node.js can be extended with C/C++ libraries
• Clustering based on OS-level socket sharing
• High performance evented I/O at its core (libuv)
• Single-threaded so no synchronization issues or locks
* The not-so-great:
• Garbage collection is slow
• Memory usage can easily get out of control
DESIGN GOAL: HIGH PERFORMANCE
STREAMING, ASYNCHRONOUS UI RENDERING
• Why?
• Start rendering the template immediately• Give the browser a head start• Let the template drive the data• Minimize idle time on the server
DESIGN GOAL: HIGH PERFORMANCE
HTMLTemplate
ASYNCHRONOUS UI RENDERINGDESIGN GOAL: HIGH PERFORMANCE
Tra
dit
ion
alC
ub
eJS
View Model
No Delay
Data Providers
1. Setup data providers2. Go straight to the
template!
ControllerInput
HTMLTemplateView Model
Long Delay
ControllerInput
1. Make service calls2. Wait for all data to come back3. Prepare view model
Raptor TemplatesExtensible, high performance, asynchronous
template rendering engine for JavaScript that works on both the server and the client
DESIGN GOAL: HIGH PERFORMANCE
MORE INFO:Raptor Templates: http://raptorjs.org/raptor-templates/
DESIGN GOAL:ROBUST
cluster2DESIGN GOAL: ROBUST
MORE INFO:https://github.com/cubejs/cluster2
• Multi-process cluster management• Live production debugging• Monitoring• Idle timeouts• Pause and resume (out-of-traffic GC!)• Process warm-up (coming soon)• Shared cache (coming soon)
Monitoring Infrastructure
DESIGN GOAL: ROBUST
Adapted to eBay Ops Monitoring Tools
Automated Testing
DESIGN GOAL: ROBUST
• Netmorphic
• Simulate network failures and slowness• Mocha
• Asynchronous tests• Code coverage reporting
• JSHint
• Flexible JavaScript static code analysis tool• Casper + PhantomJS (in-progress)
• Headless browser testing• Jenkins CI
Configuration Management
DESIGN GOAL: ROBUST
• Per-module configuration
• Real-time configuration updates
• Configuration repository based on MongoDB
ASYNCHRONOUS PROGRAMMING USING PROMISES
All CubeJS modules have standardized on promises for asynchronous programming.
Example:
Q()
.then(loadUserPreferences)
.then(performSearch)
.then(renderSearchResults)
.fail(function(error) {
res.end();
console.error("Something went wrong!")
})
ADOPTION:PULL RATHER THAN PUSH
• 10+ customers before CubeJS goes GA
• Several live CubeJS applications running in production
• Overwhelming attendance of CubeJS Tech Talks
• “Word of Mouth” spreading within eBay application teams
• No need to push