-
Notifications
You must be signed in to change notification settings - Fork 2
Use http server over local domain socket instead of json-socket #3
Conversation
A couple more things worth mentioning:
|
package.json
Outdated
"json-socket": "^0.3.0", | ||
"express": "^4.16.2", | ||
"body-parser": "^1.18.2", | ||
"fastify": "^0.35.7", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it doesn't seem like you use fastify in code
src/connectStoreController.ts
Outdated
setTimeout(resolve, 100) | ||
}).then(() => { | ||
return retryRequest(options) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can use p-limit
src/connectStoreController.ts
Outdated
import JsonSocket = require('json-socket') | ||
import net = require('net') | ||
|
||
import request = require('request-promise-native') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use node-fetch instead
src/createServer.ts
Outdated
err, | ||
}, (merr) => merr && console.error(merr)) | ||
}) | ||
function garbageCollectResponses (packageResponses: object, msgId: string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can have 2 separate dictionaries and you won't need this function
src/createServer.ts
Outdated
limit: '10mb', | ||
})) | ||
|
||
app.post('/requestPackage', async (request: Request, response: Response) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of the separate actions, it might be faster to have a single route with a switch inside.
I made the following changes:
The only thing I didn't do is replacing Is |
The reason I asked to remove the request usage is because we had an issue
with it. See pnpm/pnpm#953 . The reason I asked
node-fetch is because we already use it.
…On Tue, Dec 19, 2017, 12:44 Emanuele Tamponi ***@***.***> wrote:
I made the following changes:
- Removed express, now using the raw http server and a switch clause
-- it supports errors too now
- Added p-limit
- Split packageResponses into two separate dictionaries
The only thing I didn't do is replacing request-promise-native with
node-fetch, as I wasn't able to figure out how node-fetch handles error
conditions. The docs say it would throw a FetchError, but in my tests:
https://glitch.com/edit/#!/fastify-test?path=server.js:56:15 it does not
happen.
Is node-fetch better, or can we leave request-promise-native as it seems
it is working quite well? (We also use it on the Glitch source code without
any issues).
—
You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub
<#3 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AB1pm9-az1UO1VXVIbxOayvf-hgsqQy1ks5tB5N4gaJpZM4RGKDW>
.
|
Thanks, I'll make sure I replace it with node-fetch then!
Can you help me figure out how error conditions are handled by node-fetch?
If the remote resource returns a 500, shouldn't the fetch promise be
rejected? I see it being resolved instead...
Il 19 dic 2017 11:59, "Zoltan Kochan" <[email protected]> ha scritto:
… The reason I asked to remove the request usage is because we had an issue
with it. See pnpm/pnpm#953 . The reason I asked
node-fetch is because we already use it.
On Tue, Dec 19, 2017, 12:44 Emanuele Tamponi ***@***.***>
wrote:
> I made the following changes:
>
> - Removed express, now using the raw http server and a switch clause
> -- it supports errors too now
> - Added p-limit
> - Split packageResponses into two separate dictionaries
>
> The only thing I didn't do is replacing request-promise-native with
> node-fetch, as I wasn't able to figure out how node-fetch handles error
> conditions. The docs say it would throw a FetchError, but in my tests:
> https://glitch.com/edit/#!/fastify-test?path=server.js:56:15 it does not
> happen.
>
> Is node-fetch better, or can we leave request-promise-native as it seems
> it is working quite well? (We also use it on the Glitch source code
without
> any issues).
>
> —
> You are receiving this because your review was requested.
>
>
> Reply to this email directly, view it on GitHub
> <#3 (comment)>, or mute
> the thread
> <https://github.com/notifications/unsubscribe-
auth/AB1pm9-az1UO1VXVIbxOayvf-hgsqQy1ks5tB5N4gaJpZM4RGKDW>
> .
>
--
Zoltan
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#3 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAjUNL16ByDJMH5j_0AiwLoaHiKypAdFks5tB5crgaJpZM4RGKDW>
.
|
Probably you have to check status codes. Seems like it throws an error only
when a request couldn't be done. A 500 response is still a completed
request.
On Tue, Dec 19, 2017, 13:03 Emanuele Tamponi <[email protected]>
wrote:
… Thanks, I'll make sure I replace it with node-fetch then!
Can you help me figure out how error conditions are handled by node-fetch?
If the remote resource returns a 500, shouldn't the fetch promise be
rejected? I see it being resolved instead...
Il 19 dic 2017 11:59, "Zoltan Kochan" ***@***.***> ha
scritto:
> The reason I asked to remove the request usage is because we had an issue
> with it. See pnpm/pnpm#953 . The reason I
asked
> node-fetch is because we already use it.
>
> On Tue, Dec 19, 2017, 12:44 Emanuele Tamponi ***@***.***>
> wrote:
>
> > I made the following changes:
> >
> > - Removed express, now using the raw http server and a switch clause
> > -- it supports errors too now
> > - Added p-limit
> > - Split packageResponses into two separate dictionaries
> >
> > The only thing I didn't do is replacing request-promise-native with
> > node-fetch, as I wasn't able to figure out how node-fetch handles error
> > conditions. The docs say it would throw a FetchError, but in my tests:
> > https://glitch.com/edit/#!/fastify-test?path=server.js:56:15 it does
not
> > happen.
> >
> > Is node-fetch better, or can we leave request-promise-native as it
seems
> > it is working quite well? (We also use it on the Glitch source code
> without
> > any issues).
> >
> > —
> > You are receiving this because your review was requested.
> >
> >
> > Reply to this email directly, view it on GitHub
> > <#3 (comment)>, or
mute
> > the thread
> > <https://github.com/notifications/unsubscribe-
> auth/AB1pm9-az1UO1VXVIbxOayvf-hgsqQy1ks5tB5N4gaJpZM4RGKDW>
> > .
> >
> --
>
> Zoltan
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <#3 (comment)>, or mute
> the thread
> <
https://github.com/notifications/unsubscribe-auth/AAjUNL16ByDJMH5j_0AiwLoaHiKypAdFks5tB5crgaJpZM4RGKDW
>
> .
>
—
You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub
<#3 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AB1pm7pMfl6P-Iy3f6vVmGvXg7JClrReks5tB5f-gaJpZM4RGKDW>
.
|
Unfortunately I couldn't use You're right: request was causing some issues, including the random ECONNRESET errors. With got, in theory, we can remove the limit on the number of inflight requests. I think it is better to leave it though. |
With the last commit I made the tests pass on my local machine, I hope travis is happy too :) UPDATE: looks like Node 4 doesn't like my changes, I don't know why... UPDATE 2: Fixed tests on Node 4 too :) |
Well done! I'll review this tonight |
package.json
Outdated
@@ -38,7 +38,11 @@ | |||
"@pnpm/logger": "^1.0.0", | |||
"@pnpm/npm-resolver": "^0.3.1", | |||
"@pnpm/tarball-fetcher": "^0.3.1", | |||
"@types/got": "^7.1.6", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
type dependencies of prod dependencies should be also prod dependencies
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
src/connectStoreController.ts
Outdated
} else { | ||
remotePrefix = `http://${initOpts.hostname}:${initOpts.port}` | ||
} | ||
const limitedRetryFetch = retryFetch.bind(null, pLimit(100)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd make the concurrency configurable
src/connectStoreController.ts
Outdated
if (initOpts.path) { | ||
remotePrefix = `http://unix:${initOpts.path}:` | ||
} else { | ||
remotePrefix = `http://${initOpts.hostname}:${initOpts.port}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be fine to pass in the formed path, these manipulations can be done by pnpm
src/connectStoreController.ts
Outdated
method: 'POST', | ||
}) | ||
return JSON.parse(response.body) | ||
}).catch((e) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can use async/await syntax here with a regular try/catch
also, I think the try/catch should be inside the function and cover just the got()
call, as errors by JSON.parse
will always be passed through
src/connectStoreController.ts
Outdated
if (!e.message.startsWith('Error: connect ECONNRESET') && !e.message.startsWith('Error: connect ECONNREFUSED')) { | ||
throw e | ||
} | ||
return retryFetch(limit, url, body) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got()
supports retries out of the box, so I guess this logic is no longer needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and is there a way to tell got to retry as many times as it's needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, by default it reties 2 times
https://www.npmjs.com/package/got#retries
src/createServer.ts
Outdated
await store.saveState() | ||
return | ||
|
||
switch (req.url) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the switch statement should be probably executed early, because if an unknown route is requested, there's no need to read the data
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The switch cannot be executed early because we don't have the body until the request has been received, and I don't see any reason to add complexity to wait for the body since we always need the body or it is empty so it doesn't add overhead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't the URL known from the very start? The URL can be validated before collecting the body
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and once we validate the URL? We've to wait for the body... so I am not really sure why we should validate the URL first
src/createServer.ts
Outdated
case '/saveState': | ||
await store.saveState() | ||
res.end(JSON.stringify('OK')) | ||
break | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if no route was matched, I think a 404 response should be returned
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right 👍
It might be a good idea to prefix the routes with a version, like |
Where are the changes in |
EDIT: I was using |
It is updated automatically when you install/uninstall with pnpm. |
Just pushed the fixes following your suggestions:
|
src/connectStoreController.ts
Outdated
method: 'POST', | ||
retries: 1000, // picking a very large number to be sure it keeps retrying as long as needed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure this is a good idea because, with each retry, the delay is increased. So eventually it will just hang up. It can be considered a silent error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll pass a function with a fixed delay instead
Sorry, last 2 requests.
|
I closed this PR and created a new one with the changes and commit you asked |
These changes don't work with Windows. The previous implementation worked on Windows |
What exactly doesn't work? Probably the |
Yes, that might be the case, as the URL contains |
I don't have access to a Windows machine unfortunately, I can ask a coworker later on though. In the meantime, it should be possible to use localhost connections on Windows instead of a socket. |
We have appveyor tests on windows. They fail now https://ci.appveyor.com/project/zkochan/pnpm-17nv8/build/2015 I can also look into it, but only in the evening |
I fixed it by using localhost connection but it may have to be changed back to IPC in the future, for consistency and speed, on all systems |
The code isn't great because it's my first attempt at TypeScript, but:
Moreover, I found that the same problem that afflicted json-socket was causing issues with the http servers as well (included fastify): at the end I found that we were overloading the socket. In the
retryRequest
function you'll see that I put a simple backoff timeout if there are too many requests in flight. Probably we can port this backoff code back to json-socket so that it works too, if you like it more than the http approach.