Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: handle big integers in incoming events #495

Merged
merged 2 commits into from
May 10, 2023

Conversation

lance
Copy link
Member

@lance lance commented Jun 14, 2022

An event may have data that contains a BigInt. The builtin JSON parser
for JavaScript does not handle the BigInt types. The introduced
json-bigint dependency (34k) does.

Fixes: #489

Signed-off-by: Lance Ball lball@redhat.com

@lance lance requested a review from a team June 14, 2022 20:33
@lance lance self-assigned this Jun 14, 2022
@lance lance added the type/fix A change that fixes something that is broken label Jun 14, 2022
Copy link

@cardil cardil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot @lance for fixing this. It looks good, but I found some doubts about this proposal.

src/parsers.ts Outdated Show resolved Hide resolved
@@ -4,6 +4,7 @@
*/

import { types } from "util";
import JSON from "json-bigint";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you measured the impact of using this library versus using a native V8 implementation?

If the difference is significant (it might be), we should consider gating this behavior with a configuration option (it may be turned on by default IMHO).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good point, so I decided to try a simple, probably naive test. But no matter how naive, you can't ignore a 7x slowdown with bigint support.

❯ time node index.js
Unsing native JSON
....................................................................................................
node index.js  199.67s user 1.29s system 98% cpu 3:23.76 total

❯ time node index.js bigint
Using bigint
....................................................................................................
node index.js bigint  1308.75s user 4.49s system 99% cpu 21:55.06 total

❯ cat index.js
   1   │ const fs = require('fs');
   2   │
   3   │ const J = require('json-bigint')({ useNativeBitInt: true });
   4   │ let Parser;
   5   │
   6   │ if (process.argv[2] === 'bigint') {
   7   │   Parser = J;
   8   │   console.log('Using bigint');
   9   │ } else {
  10   │   Parser = JSON;
  11   │   console.log('Unsing native JSON');
  12   │ }
  13   │
  14   │ const json = fs.readFileSync('./generated.json');
  15   │
  16   │ let remain = 10_000_000;
  17   │ while (remain-- > 0) {
  18   │   Parser.parse(json);
  19   │   if (remain%100000 === 0) {
  20   │     process.stdout.write('.');
  21   │   }
  22   │ }
  23   │
  24   │ console.log();

There is no obvious place to set global parser variables. I need to think on this a bit.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lance Have you thought of where to place this feature flag?

@lance
Copy link
Member Author

lance commented Jun 14, 2022

Closing and reopening to trigger re-run of CI with updated package.json (to hopefully fix errors)

@lance lance closed this Jun 14, 2022
@lance lance reopened this Jun 14, 2022
@lance lance force-pushed the lance-489-big-int branch from ba0c724 to 47bf946 Compare June 15, 2022 16:34
@lance lance mentioned this pull request Jun 21, 2022
@github-actions
Copy link
Contributor

This pull request is stale because it has been open 30 days with no activity.

An event may have data that contains a BigInt. The builtin `JSON` parser
for JavaScript does not handle the `BigInt` types. The introduced
`json-bigint` dependency (34k) does.

Fixes: cloudevents#489

Signed-off-by: Lance Ball <lball@redhat.com>
@lance
Copy link
Member Author

lance commented May 8, 2023

@cardil I have added an environment variable to enable the json-bigint module. I'm not a huge fan of this approach because the check is made for each call to the parser. The library does not have an obvious place to set flags or other static values. An alternative approach would be to add this as an option to the HTTP.toEvent() method, but that changes the method signature resulting in a lot of small changes all over the codebase.

@lholmquist ptal

Signed-off-by: Lance Ball <lball@redhat.com>
Copy link
Contributor

@lholmquist lholmquist left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm.

I do like your suggestion of adding this to the method signature, which as you said is a bigger change, but maybe we can do that later then

@lance lance merged commit 43c3584 into cloudevents:main May 10, 2023
@lance lance deleted the lance-489-big-int branch May 10, 2023 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/fix A change that fixes something that is broken
Projects
None yet
Development

Successfully merging this pull request may close these issues.

bug: parsing big integers in JSON data loses precision
4 participants