-
-
Notifications
You must be signed in to change notification settings - Fork 32
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
Speed up token generation #14
base: master
Are you sure you want to change the base?
Conversation
Needs to at least support Node.js 0.8. What makes it quicker? Is it not possible to speed up our existing dependencies? I have not had great experience with third party dependencies, especially when they seem to very quickly discard support for old Node.js versions. Now, that's their own opinion, though I try to support as far down as is reasonable with the CI infrastructure (which is 0.8 currently). |
Yeap, I support Promise-less environment and it is written by the simple ES5. I especially made few changes to Nano ID to pass
Thanks for answering =^_^= In secure generator it happens because of we manager with Buffers in a more optimized way. In non-secure we used a cool trick with
It is possible in theory. But do you want to spend time on maintaining multiple projects and copy ideas every time, when there is a good well-maintained project, which always tries to find a tricky way of optimization? =^_^= (we are focusing not only on performance but also of client-side size) |
Ah, sorry, I assumed it didn't because the Node.js 0.8 CI failed for this PR and I looked at the module and it doesn't have any CI for Node.js 0.8 so assumed there is no support. If there is no CI, what is the guarantee that 0.8 is a supported platform in an ongoing fashion?
Right, I definitely would rather use external deps when possible if they exist and they seem to be aligned with the same target support environments. |
Jest doesn’t support Node.js 0.8 to run a test on CI :(. I think right now most of the test runners drop even Node.js 4 support. Maybe I can write a script to test critical things manually. Or maybe you have a better idea? |
Yea, I don't have a better idea besides just using a testing framework that does support 0.8 (which is what this module does). In my opinion testing frameworks should be supporting pretty much every possible version since they are going to influence what environments real modules can support. But maybe those test frameworks want to use their power to dictate the versions of Node.js people will support, idk. Coming from the Perl system Node.js feels very fractured to me, with constant major versions of Node.js and module authors quickly discarding support for Node.js versions :( |
Totally agree. I fight with Jest community for a few months for Node.js 4 even at the moment when it was still LTS. Fair enough note about CI and Node.js 0.8. I will try to fix it soon. |
Done. I added Node.js 4, 0.12 and 0.8 to CI: https://travis-ci.org/ai/nanoid It was tricky, since |
@dougwilson I thought about how to fix npm error in But maybe it is just a cache issue and if we will call it again, it will be installed? |
We released Nano ID 1.3.1. It contains client-side optimization (not important for Node.js version). But maybe you will like the way. We wrote a bruteforcer to find the most gzip-friendly alphabet symbols order. Also, your suggestion testing Nodejs 0.8 found an issue in Travis CI. Not it is fixed. |
@dougwilson if you don’t want to speed up it by some reason, just say it. It is not a big deal for me, but I will be able to remove Node.js 0.8—4 support code (it was added only to fit |
I just need the CI to pass here to merge... |
@dougwilson sure. I wrote to npm support to ask about storage npm behaviour on Node.js 0.8. |
@dougwilson done, I fixed CI 🎉 |
Hi @ai, awesome just saw that 🎉 . But this looks like a breaking change: it would no longer install on machines that it used to install on. Our current dependencies don't have any issue with the verison of npm that is included with Node.js 0.8. Is there any particular reason why this new module does not support the same npm version? At minimum, if a higher version of npm is required, can you update the Circling back around, is there any way that this new module can just run under the same version of npm the rest do? Or should this just become a larger discussion around it being a major breaking change? |
I asked npm support. I think Node.js 0.8 is too old for npm and they serve old registry for this old npm. |
Strange. Most of all my modules are Node.js 0.8+ and even ones I released last week install on Node.js 0.8 without issue, with the npm that is included out-of-the-box (npm 1.2.30). |
This is a fresh build of |
@dougwilson I agree that it is strange. Let’s wait for npm support answer. |
👍 there is an unreleased change to |
So speaking of Node.js 0.8, I was playing around with this PR on Node.js 0.8 on my machine and I encountered a bug I basically forgot about: #10 (comment) Basically in Node.js 0.8 (and 0.10, perhaps some more), the underlying crypto engine in OpenSSL will sometimes throw an error that it's not seeded when the process starts and you try to grab random bytes too fast. To solve that issue, I ended up creating the module https://github.com/crypto-utils/random-bytes and that is used in turn by Is it possible to get this work-around added to the |
Sure, I can add it. |
@dougwilson I found a way to fix npm issue in Node.js 0.8 without updating npm (npm 1.x can’t understand |
I will release new Nano ID with OpenSSL issue fix in next hour |
Oh, nice, I didn't even realize that was there in the PR. I always pin dependency versions anyway to specific versions such that I can see what the changes are before users installing these modules suddenly encounter changes. It has helped a lot in the past especially when a dependency accidentally releases a breaking change to a subset of users but it takes a long time to get it resolved, and users usually are not sure where to report the issue to. |
@dougwilson done:
|
Awesome, @ai ! Let me just finish up this release of |
Hi @ai , sorry to come back again 😢. So I tested the updated PR (and yes, it installed nanoid 1.3.2), and I still had the same issue, the seed error. I hooked up a debugger and stepping through the code, it looks like there is still no handling to retry for the error in the code. The very high-level code that triggers the code path is What I'm finding is that That in turn calls the This just ends up being a direct reference to I hope that helps! I also finished the simple benchmarks I promised and pushed to
A typical application embedding this module has the flow of (1) call What this means that the typical hot path in an app is the Ideally the hot path is the best one to get a speed boost, so I was kind of surprised (at least on my machine) to see the performance go down in the spot that is going to be the hottest path. I'm not sure yet what is causing the decrease, but the increase in For reference these are the comparisons on my machine: master
pr-14
P.S. thanks for being so responsive. You rock! |
Oh, yeap. I add I also will think about verify performance drop |
@dougwilson what Node.js version do you? Some optimization (like that asm.js optimisation for |
Hi @ai I was using Node.js 8.12.0, which was the version "recommended for most users" just as of last week, though they rolled over the versions now. I was just testing on what I have most of my production projects running on just as a quick test. |
I added |
I found that if we will remove Can I ask you to run both branches 5 times, to get a more stable result? If not, we can keep |
Yes, I will run again another day; it's quite late here and I already signed off and am just on the phone. Just didn't want to leave you hanging when I saw your message. |
@dougwilson I found the reason :D. As result, I replaced |
Ah, I guess that makes sense. Sorry I was gone for a few days, I apologize. I am taking a final look over this today and was just testing it in some apps. I found a case that was accidentally not covered in the tests in this module and instead we accidentally relied on the I also noticed in an app that the character set seems to have changed and there is now a Would it be OK if I pushed to this PR the following changes?
I already started on those changes, just since I see you've been squashing your commits together, I didn't want to surprise with a change showing up on your branch the next time you went to force push. |
Done
Done
We used Maybe I should just release 2.0 with |
@dougwilson I released Nano ID 2.0 with |
Awesome thanks. I just pushed up the change for (1) and (2) as well to this PR so now all three points are hit. I'll be back at work tomorrow to test those apps again before merge :D |
P.S. I know you said the reason |
Yeap, I added |
Also (sorry, trying to just get as much done tonight to hurry this PR out tomorrow), I'm curious about this part: it seems like there are more bytes getting pulled from the OpenSSL random pool with |
It happens, because of Nano ID generate every byte to char. Yeap, it is a good point for optimization. I created issue. Let’s make it faster a little later. |
I saw it first on a custom Node.js build that is using the Windows Crypto instead of OpenSSL, so then wanted to quickly validate it by switching to a standard Node.js linked against OpenSSL and added the following simple code to see the requested size: diff --git a/test/test.js b/test/test.js
index a9161f4..de8529a 100644
--- a/test/test.js
+++ b/test/test.js
@@ -1,6 +1,17 @@
var assert = require('assert')
var crypto = require('crypto')
+var _randomBytes = crypto.randomBytes
+var _randomFillSync = crypto.randomFillSync
+crypto.randomBytes = function () {
+ console.dir(arguments[0])
+ return _randomBytes.apply(this, arguments)
+}
+crypto.randomFillSync = function () {
+ console.dir(arguments[0].length)
+ return _randomFillSync.apply(this, arguments)
+}
+
var Promise = global.Promise || require('bluebird')
var Tokens = require('..') Running |
I just tried the following patch, which forces diff --git a/test/test.js b/test/test.js
index a9161f4..b66a30a 100644
--- a/test/test.js
+++ b/test/test.js
@@ -1,6 +1,13 @@
var assert = require('assert')
var crypto = require('crypto')
+var _randomBytes = crypto.randomBytes
+crypto.randomBytes = function () {
+ console.dir(arguments[0])
+ return _randomBytes.apply(this, arguments)
+}
+crypto.randomFillSync = null
+
var Promise = global.Promise || require('bluebird')
var Tokens = require('..') |
Yeap, it happens because of different stringification algorithm. I will optimize it after my vacation. I think it could give us a few extra % of performance. |
Do we have anything else to fix? |
@dougwilson I tried
Seems like take few extra random bytes is better |
@dougwilson if extra random bytes is a deal breaker for you, please close PR. I do not have a solution right now (old way will slow down generation). Maybe I will find out later. But this PR is already taking too many forces from me. Keeping it open is bad for our minds, it will just frustrate us and keep the dangerous fear of any changes. |
@dougwilson I will remove |
@dougwilson ping |
@dougwilson Hi. Seems like you reduce your GitHub activities. I hope everything is OK. I continue to ping you, since Nano ID contains changes, which are important only for |
This PR reduces dependencies number (from 3 to 1) and should a little improve performance according to this benchmark with the same security (
nanoid
use the same hardware random generator; it’s popular and well maintained).@dougwilson what do you think? Should I rename
nanoidFast
tonanoidNonSecure
in R to be more clear?