• Stars
    star
    139
  • Rank 257,644 (Top 6 %)
  • Language
    JavaScript
  • License
    Other
  • Created over 6 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Asynchronous JSON parser and stringify APIs that make use of generator patterns

Asynchronous JSON.parse and JSON.stringify APIs

yieldable-json

This library provides asynchronous version of standard JSON.parse and JSON.stringify APIs.

Use Case

Node.js based web applications dealing with large JSON objects while requiring high level of concurrency for the transactions.

Here 'largeness' applies to any of, or all of, or any combination thereof deep compositions, large number of fields, and fields with large data (such as massive strings).

In contrast to JSON Streams, which are built with custom stream oriented protocols (at library as well as application level) and used in special use cases like data analytics, monitors, etc., yieldable-json works on fully formed JSON data that is characterized only by object size and designed with an objective of improving concurrency in the application and thereby usable in any workload scenarios.


Statistics

Testing with a wide range of data showed that objects which are bigger than 256KB (when stringified) degrades concurrency in the application.

While definition of concurrency is subjective, a number of tests we performed in short and long round-trip networks showed that being available in the event loop for attending to concurrent requests at every 5 milliseconds provides the required responsiveness to clients, as well as meets the overall concurrency expectation on the application.

Data Volume Loop starvation (in milliseconds)
JSON (built-in) yieldable-json
115 KB 2 5
327 KB 10 5
1.3 MB 50 5
2.2 MB 100 5

As shown in the table, the yieldable-json guarantees the event loop is reached and processed in every 5 ms, irrespective of the JSON volume being processed.


Background

In Cloud based deployments, we foresee increase of JSON payload across distributed computing end-points in an exponential manner, causing performance bottleneck in the single-threaded node.js platform, and hence this attempt. The key function of asynchronous JSON APIs are to perform marshalling and un-marshalling of massive data incrementally, and yielding back to the application occasionally, and reduce loop starvation.

The ES6's generator function along with yield semantics is used for implementing incremental traversal. The extent of traversal in one iteration is controlled by the intensity parameter. While there are some globally accessible variables within main APIs, predominently the parser and stringifier is implemented through a self-recursing loop. The callback is guaranteed to fire no earlier than next tick to emulate the asynchronous behavior.

Because of the usage of ES6 semantics, this module is supported only on node v4.x and above.


APIs

stringifyAsync:

stringifyAsync(value[, replacer][, space][, intensity], callback)

  • value <Object> The javascript object which need to be converted to its equivalent JSON string.

  • replacer Optional <Function> | <Array> As a function, it takes two parameters, the key and the value being stringified. The object in which the key was found is provided as the replacer's this parameter. Initially it gets called with an empty key representing the object being stringified, and it then gets called for each property on the object or array being stringified. It should return the value that should be added to the JSON string, as follows:

  1. If you return a String, that string is used as the property's value when adding it to the JSON string.
  2. If you return a Boolean, "true" or "false" is used as the property's value, as appropriate, when adding it to the JSON string.
  3. If you return any other object, the object is recursively stringified into the JSON string, calling the replacer function on each property, unless the object is a function, in which case nothing is added to the JSON string.
  4. If you return undefined, the property is not included (i.e., filtered out) in the output JSON string.
  • toJSON() behavior If an object being stringified has a property named toJSON whose value is a function, then the toJSON() method customizes JSON stringification behavior: instead of the object being serialized, the value returned by the toJSON() method when called will be serialized.

  • space Optional <string> | <number> Used to insert white space into the output JSON string for readability purposes. If this is a Number, it indicates the number of space characters to use as white space; this number is capped at 10 (if it is greater, the value is just 10). Values less than 1 indicate that no space should be used. If this is a String, the string (or the first 10 characters of the string, if it's longer than that) is used as white space. If this parameter is not provided (or is null), no white space is used.

  • intensity Optional <number> Takes the value between the range 1-32. This is used to compute the extent of traversal in the object tree in one iteration. The more the intensity, the more time will be spent in the stringify operation before it yields back to the uv loop. Its default value is 1.

  • callback <Function> Called with result when the stringify operation completes.

const yj = require('yieldable-json')
yj.stringifyAsync({key:"value"}, (err, data) => {
  if (!err)
    console.log(data)
})

Warning: While stringifyAsync is in progress (i.e. before the callback is executed), it is the user's responsibility to ensure that the Javascript object value (or any of its child objects) is not modified in any way. Object modification between the async function invocation and issuing of the completion callback may lead to undefined behavior (and can possibly result in an inadvertent crash or object corruption).

parseAsync:

parseAsync(text[, reviver][, intensity], callback)

  • text <string> The JSON string which needs to be parsed.

  • reviver Optional <Function> A function if specified, the value computed by parsing is transformed before being returned. Specifically, the computed value and all its properties (beginning with the most nested properties and proceeding to the original value itself) are individually run through the reviver. Then it is called, with the object containing the property being processed as this, and with the property name as a string, and the property value as arguments. If the reviver function returns undefined (or returns no value, for example, if execution falls off the end of the function), the property is deleted from the object. Otherwise, the property is redefined to be the return value. If the reviver only transforms some values and not others, be certain to return all untransformed values as-is, otherwise they will be deleted from the resulting object.

  • intensity Optional <number> Takes the value between the range 1-32. This is used to compute the extent of traversal in the JSON string in one iteration. The more the intensity, the more time will be spent in the parse operation before it yields back to the uv loop. Its default value is 1.

  • callback <Function> Called with result when the parsing operation completes.

const yj = require('yieldable-json')
yj.parseAsync('{"key":"value"}', (err, data) => {
  if (!err)
    console.log(data)
})

GitHub Issues

This project uses GitHub Issues to track ongoing development and issues. Be sure to search for existing bugs before you create another one. Contributions are always welcome!

Collaborators

More Repositories

1

v8ppc

Port of Google V8 javascript engine to PowerPCยฎ
C++
94
star
2

openj9-openjdk-jdk9

Extensions for OpenJDK for Eclipse OpenJ9
Java
67
star
3

openj9-openjdk-jdk8

Extensions for OpenJDK8 for Eclipse OpenJ9
Java
53
star
4

ci.docker

Dockerfiles and build scripts for generating various Docker Images related to IBM Runtimes
Shell
46
star
5

v8z

Port of Google V8 JavaScript engine to z/OS. The Linux on Z port is maintained in the community: https://chromium.googlesource.com/v8/v8.git
C++
42
star
6

semeru17-binaries

The home for releases and nightlies for all IBM Semeru Runtimes for Java 17 binaries
31
star
7

openj9-openjdk-jdk11

Extensions for OpenJDK 11 for Eclipse OpenJ9
Java
31
star
8

zoslib

z/OS C/C++ runtime library
TeX
25
star
9

openj9-openjdk-jdk17

Extensions for OpenJDK 17 for Eclipse OpenJ9
Java
22
star
10

openj9-openjdk-jdk

Extensions for OpenJDK for Eclipse OpenJ9
Java
15
star
11

semeru8-binaries

The home for releases and nightlies for all IBM Semeru Runtime for Java 8 binaries
14
star
12

spelk

Reporting Apache Spark metrics to Elasticsearch
Java
13
star
13

Semeru-Runtimes

Issue repo for all things IBM Semeru Runtimes
Standard ML
12
star
14

vsam.js

Reading and writing vsam files using NodeJS
C++
10
star
15

openj9-openjdk-jdk10

Extensions for OpenJDK for Eclipse OpenJ9
Java
10
star
16

go-recordio

Record I/O in Go: a Go module for record I/O in VSAM databases directly from Go (no need for cgo)
Go
7
star
17

openj9-openjdk-jdk21

Java
7
star
18

node-racf

Node RACF npm
C++
6
star
19

semeru11-binaries

The home for releases and nightlies for all IBM Semeru Runtimes Open Edition for Java 11 binaries
6
star
20

chcp

This library provides native bindings for Windows APIs
JavaScript
5
star
21

openj9-openjdk-jdk19

Extensions for OpenJDK 19 for Eclipse OpenJ9
Java
4
star
22

blrmeetups

4
star
23

semeru18-binaries

About The home for releases and nightlies for all IBM Semeru Runtimes for Java 18 binaries
4
star
24

openj9-openjdk-jdk12

Extensions for OpenJDK 12 for Eclipse OpenJ9
Java
4
star
25

semeru21-binaries

The home for releases for IBM Semeru Runtimes for Java 21 binaries
4
star
26

openj9-openjdk-jdk13

Extensions for OpenJDK 13 for Eclipse OpenJ9
Java
4
star
27

InstantOnStartupGuide

Setup scripts to get started with InstantOn
Shell
3
star
28

java-resource-monitor

Tool/agent for monitoring resources consumed by JVM/Java application
Java
3
star
29

semeru16-binaries

The home for releases and nightlies for all IBM Semeru Runtime for Java 16 binaries
3
star
30

zrexx

Call ZOS REXX scripts reside in PDS from node-js with IRXEXEC
C++
3
star
31

openj9-openjdk-jdk15

Extensions for OpenJDK 15 for Eclipse OpenJ9
Java
2
star
32

mvsutils

Node.js interface to z/OS resources
C++
2
star
33

openj9-openjdk-jdk.valuetypes

Java
2
star
34

openj9-openjdk-jdk14

Extensions for OpenJDK 14 for Eclipse OpenJ9
Java
2
star
35

semeru17-certified-binaries

The home for releases for IBM Semeru Runtimes Certified Edition for Java 17 binaries
2
star
36

acmeair-modular

Java
2
star
37

queryendpoint

Rust
1
star
38

openj9-openjdk-jdk20

Extensions for OpenJDK 20 for Eclipse OpenJ9
Java
1
star
39

openj9-openjdk-jdk18

Extensions for OpenJDK 18 for Eclipse OpenJ9
Java
1
star
40

nodejs-bpxwdyn

Node.js interface to BPXWDYN (Dynamic allocation via SVC99)
C++
1
star
41

semeru-openjdk-jdk17

Semeru fork of openj9-openjdk-jdk17
Java
1
star
42

node-zcrypto

z/OS RACF + Crypto module for Node.js
C++
1
star
43

semeru11-certified-binaries

The home for releases for IBM Semeru Runtimes Certified Edition for Java 11 binaries
1
star
44

semeru-openjdk-jdk11

Semeru fork of openj9-openjdk-jdk11
Java
1
star
45

semeru19-binaries

The home for releases for IBM Semeru Runtimes for Java 19 binaries
1
star
46

openj9-openjdk-jdk22

Java
1
star
47

semeru20-binaries

The home for releases for IBM Semeru Runtimes for Java 20 binaries
1
star