-
Notifications
You must be signed in to change notification settings - Fork 9
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
New post consumer component #52
New post consumer component #52
Conversation
@@ -68,3 +68,6 @@ test/test_result/ | |||
|
|||
#config | |||
configuration.js | |||
|
|||
#IDE-specific | |||
.idea |
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.
Just for your information, you can exclude local-specific files (as IDE or personal directories) in .git/info/exclude
file. You can do it for each project or all of the projects of your machine (avoid changing .gitignore
of each project you contribute on).
This file already exclude environment-specific files, so do not change here, it is only an information. 🙂
static/tag/webhook-editor.tag
Outdated
<webhook-editor> | ||
<!-- bouton aide --> | ||
<div class="contenaireH" style="margin-left:97%"> | ||
<a href="https://github.com/assemblee-virtuelle/Semantic-Bus/wiki/Composant:-Webhook" target="_blank"><img src="./image/help.png" alt="Aide" width="25px" height="25px"></a> |
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.
Aide
? I do not see the bond between aide
and webhook.
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.
This is the alt
tag over the help icon. I've copied what is done in other .tag
files.
static/tag/webhook-editor.tag
Outdated
this.updateData = function (dataToUpdate) { | ||
this.data = dataToUpdate; | ||
this.update(); | ||
}.bind(this); |
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.
To avoid this bind
, you can declare functions as: this.updateData = (dataToUpdate) => {…}
.
Also, you use two formats:
urlInputChanged(e) {…}
// and
this.updateData = function (dataToUpdate) {…}.bind(this);
Is it possible to keep only one of them?
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.
Ah I didn't know ES6 arrow functions could be used inside Riot tags.
I've updated the code accordingly.
|
||
// Function called when another component push to this component | ||
pull: function(data, flowData, queryParams) { | ||
return new Promise((resolve, reject) => { |
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 avoid nested promise construction:
Line 28:
return Promise.reject(new Error('...'));
Line 31+:
return this.fetch(componentData.url, {
method: 'POST',
body: body,
headers: { 'Content-Type': componentData.contentType }
}).then(() => ({ data: flowData[0].data }))
Avoiding nested promises reduces memory usage (but not strongly impacting here), enforce composition (.then
, .catch
) and avoid forgetting cases of termination (here, I do not see one, but if you forgot the .catch
, the promise will never end, remains in memory and flood the server).
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.
Great idea, it makes the code much more readable. Thanks !
@@ -65,6 +65,7 @@ | |||
"mongoose": "^5.3.2", | |||
"mongoose-unique-validator": "^2.0.2", | |||
"mysql": "^2.13.0", | |||
"node-fetch": "^2.3.0", |
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 believe in this project we use http
: https://nodejs.org/api/http.html#http_http_request_options_callback
@simonLouvet : Can you confirm?
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.
@grizio I believe the http/https
libraries (like the request
library) are fairly low-level. When you deal with more complex situations, for example if you are behind a proxy, if you need to handle CORS (?) or redirections, it will require tweaks. (I've seen that for some components, the follow-redirects
library is used just to handle the redirections.)
The advantage of node-fetch
is that it pretty much handles all cases.
Thanks for the review @grizio ! I've made some changes and comments. |
@simonLouvet I've improved the code so that, when the webhook POST fails, it retries after 5s, 25s, 2m, 10m, 50m, 4h and 21h. |
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 component name Webhook
seems valid to me. Using a name like repost to url
will give the technical behavior of the component, not its business function.
return this.fetch(url, options).catch(error => { | ||
if( numRetry >= 7 ) { | ||
// TODO log the failed webhook posts somewhere ? | ||
console.error(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.
How does the promise end in this case?
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 ends with no return value.
I don't want to rethrow the error, otherwise Node will stop.
console.log(`Webhook post to ${url} failed, trying again in ${retryInterval}s...`); | ||
|
||
return this.sleep(retryInterval * 1000).then(() => { | ||
this.call_webhook(url, options, numRetry+1); |
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.
What is the returning value of the promise in this case?
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 should return the result of this.call_webhook
. I've made the correction.
// This will retry after 5s, 25s, 2m, 10m, 50m, 4h, 21h | ||
const retryInterval = Math.pow(5, numRetry+1); | ||
|
||
console.log(`Webhook post to ${url} failed, trying again in ${retryInterval}s...`); |
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 log can be considered as an error or at least as a warning. If some endpoint is failing, we will be alerted only 26h hours later.
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 that's the idea. The URL to call may be down temporarly, IMO this shouldn't be an error.
Do you think we should do it differently ? Should I remove the console.log ?
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 log is valid, it is the level I would level up to warning at least.
Maybe not the first times, but if the URL is down 1h (or even 30m), it is already long enough to be informed and maybe to check the issue.
What about this compromise:
- if numRetry < 4 (for 10m), console.log (like today)
- else if numRetry > 7 (for 21h), console.error and stop (like today)
- else (for 10m, 50m and 4h) console.warn (new case)
It could also be a more configurable/smart strategy, I mainly give the idea.
@srosset81 name of this component is Post Consumer. @Jacx12 can you create an image for this component. Miror of flow consumer please. |
@simonLouvet @grizio I've renamed to Post consumer and made a few corrections. |
Merged. visible in production at the next Docker Push. |
This component
POST
received data to the configured URL.Currently only
application/json
ContentType is accepted.The name "Webhook" is maybe not right, I wasn't sure how to call it.
Note: this works fine if the "components chain" is in "push-only", for example if you link a "Post provider" component to this component. However if you add a "NoSQL cache" in between, the Webhook component will not be called and thus the data will not be POSTed to the configured URL.