How to log userId in a server that handles concurrent requests? - javascript

I have an express server, and it handles all kind of functionalities that I want to log. I dont want to log only incoming requests, I want to log for example how much time it took for a certain function that handles data to execute. I also have a client that passes username as a header to each request in the server, and I want the username to be a part of every log. I can't store the username in a class or a global variable, as it won't be correct when multiple requests from different users are made. My logger is a class that you can simply call in order to log, for example: logger.log("blah", payload)
I don't want to pass the userId to every function where I want to log, what can I do?
Things I thought to do:
pass userId to every function, though I don't want to do it
Maybe somehow make the req known to the logger? But I don't know how to do it correctly

Related

How to keep track of message recipient in Twilio with unique identifier?

I am currently using Twilio to send someone a text, this person/phone number is associated with a data object on the backend. When the object is created, this text is sent out with a question.
I have setup a webhook for the Twilio number so that when it receives a message, it will hit an endpoint I have setup on my server. I would like to alter the object based on the user's response.
However I cannot figure out a way to associate the text sent that corresponds with the initial object, to the text/object that I receive as a response. The messages have ID's, but those are unique to each message, they are not unique to each 'conversation' or phone number, so they are not useful for me in this scenario.
Is there a way to do this? The backend data objects have a unique ID on them, but I don't see a way to pass this around so that I can access it later once I get a response text.
SMS is stateless, so the only way to keep track of a session is to use a unique number to send the message from which isn’t realistic.
You will need to send only one message out at a time and await a response with some built in timeout on your side and then decide what to do next, send the same message or send the next message.
Another way is have them reference some value you can look for in the response body to match the response with the request.

Vue js and favorite/like button

I'm wondering how favorite, subscribe or like buttons work.
I don't understand something.
For exemple:
A user like a post with id 243.
A ajax request is sent to the server with the id of the post (243) [here comes back end stuff, the user's favorite list is updated, including that post] and the server sends back a success response.
Now, how I suppose to deal with modifying the like button to actually display that is liked (permanently, including refresh).
How can I achieve that in Vue JS. How things get updated? I don't understand this part.
If the server sends back a successful response you can increment the number that is already there.
This initial number is something you have gotten either through a prop, directly from the server or through an initial AJAX request.
If you want to "permanently" update the amount of likes on your button you have to persist it to a database(or some other storage medium). On you server you could have a route that accepts a post id as an argument and increment that specific user post:
/incrementlike/243
That is where you would make a POST ajax request to. Most of the time in an MVC framework you would have a controller action/method mapped to this route that holds the logic to respond to this call.
If you are interested in the part that happens after you make an AJAX request to the server to increment your like on the backend side, I suggest you read up on routing or MVC structure.
How you would do this is really done on a case by case basis. It really depends on a number of things, for example what your backend does to a post when it is liked.
If you would like a general 'explanation' to the process I attach it below, this is not really Vue specific, but the general idea is the same:
Frontend side:
Modify the local state of you post to set the proper flag, ex. post1.liked = true immediately when it is clicked, before sending the request to the server.
Make sure your GUI represent this change. ex. Base the color of the button on the property 'liked' of each post.
If a failure response it received from the server, notify the user and allow them to 'try again' or something similar.
When refreshing the page, make sure changes are fetched from the server, If you have done the backend part correctly, the modification of the state of the post will be correct in the data you receive from your backend (post1.liked will be true)
Backend side
When the request comes in, modify the state of the post the correct way and make sure that next time the post is fetched, the new state is sent.

Module scope in Node.js - Simultaneous Express requests

I'm using the id variable across different functions. The id is defined outside of the functions. Could this cause the variable to overwritten when receiving multiple simultaneous requests? Is the behavior the same when this is done in the browser instead of in Node.js?
var id;
server.get('/myapp', function (req, res, next) {
id = uuid.v4();
}
Yes, it causes conflicts
If your request handlers have any asynchronous operations in them which allow more than one request to be in flight at the same time, then YES, the use of a module level variable that more than one request may access will cause conflicts and one request could trounce the variable that another was using.
In a nutshell, don't do this
Module level variables are only for data that ALL requests can safely access and share. Data for a single request should be inside the request handler or a property on the request or response object or some similar-type object that is per-request and not shared among multiple requests.
Data needed only during the processing of a request
So, if you just need access to some data for the duration of this particular request, then you can put it in a local variable inside the request handler and you can pass it to any other functions you may call that need it while processing that request. Or, you can assign it as a property on the req object which is unique for each separate request and then pass the req object to any other functions you are calling that need access to the data.
Data needed from one request to the next, but different for each user
If you are trying to keep track of some data from one request to the next for one particular client, then you can't store it this way at all. You will likely need to use a session manager so you can create a lasting session that can be correlated with one particular browser from one request to the next. express-session is a popular session manager that makes it pretty easy.
The way a session manager works is that the first time a given browser hits your server, it is assigned a unique cookie. That cookie contains an encrypted session ID. Then, the session manager creates a session object that is indexed by that session ID. When a second request from the same browser comes in, then express-session gets that previously set cookie, decrypts the sessionID, looks up the corresponding session object and lets you then access any data you may have stored in the session object on behalf of this particular user.

handle HTTP time out for ajax save

I have a JavaScript application that regularly saves new and updated data. However I need it to work on slow connection as well.
Data is submitted in one single HTTP POST request. The response will return newly inserted ids for newly created records.
What I'm finding is that data submitted is fully saved, however sometimes the return result times out. The browser application therefore does not know the data has been submitted successfully and will try to save it again.
I know I can detect the timeout in the browser, but how can I make sure the data is saved correctly?
What are some good methods of handling this case?
I see from here https://dba.stackexchange.com/a/94309/2599 that I could include a pending state:
Get transaction number from server
send data, gets saved as pending on server
if pending transaction already exists, do not overwrite data, but send same results back
if success received, commit pending transaction
if error back, retry later
if timeout, retry later
However I'm looking for a simpler solution?
Really, it seems you need to get to the bottom of why the client thinks the data was not saved, but it actually was. If the issue is purely one of timing, then perhaps a client timeout just needs to be lengthened so it doesn't give up too soon or the amount of data you're sending back in the response needs to be reduced so the response comes back quicker on a slow link.
But, if you can't get rid of the problem that way, there are a bunch of possibilities to program around the issue:
The server can keep track of the last save request from each client (or a hash of such request) and if it sees a duplicate save request come in from the same client, then it can simply return something like "already-saved".
The code flow in the server can be modified so that a small response is sent back to the client immediately after the database operation has committed (no delays for any other types of back-end operations), thus lessening the chance that the client would timeout after the data has been saved.
The client can coin a unique ID for each save request and if the server sees the same saveID being used on multiple requests, then it can know that the client thinks it is just trying to save this data again.
After any type of failure, before retrying, the client can query the server to see if the previous save attempt succeeded or failed.
You can have multiple retries count as a simple global int.
You can also automatically retry, but this isn't good for an auto save app.
A third option is use the auto-save plugins for jQuery.
Few suggestions
Increase the time out, don't handle timeout as success.
You can flush output of each record as soon as you get using ob_flush and flush.
Since you are making request in regular interval. Check for connection_aborted method on each API call, if client has disconnected you can save the response in temp file and on next request you can append the last response with new response but this method is more resource consuming.

ExpressJs execute a callback after sending a response for every route

The scenario is to save the data in cache. We have numerous express routes written with complicated logic.
I have to find a way to save the response data in cache. I cannot go to each and every route and check whether this needs to be saved and save the data before sending the response. (If no other go, then this may be the way)
I have tried the following approaches.
https://nodejs.org/api/http.html#http_event_close_1 - using 'close' or 'finish', which fires after sending the response would do the trick. But there is no way I could get the response data in these events.
Also my node version is v0.10.31
Thought of using app.all('*', callback), but i am not sure how to catch the response data for cacheing.
Finally i thought of adding a second callback for routing, app.VERB(path, [callback...], callback), but upon returning the response in first callback, second callback is never called.
Hoping there is a solution for this, and I am stuck in this for more than a week.
The reason why adding logic into each and every routes is a tedious job is that, I need to add a configuration entry specifying which route needs to be cached with an expiry time.
Response needs to be cached in redis server. A cache key will be generated based on the route data and query strings. All those complete user specific information will be saved in a key.
So when the user hits the same route the key will be generated to check if it already exists using app.use and the data will be served without precedding to the successive middlewares.
Define a callback middleware as,
var storeResponseMiddleware = function(req, res, next) {
console.log("storing data in redis....")
..........more stuff
}
Add it to expressJs app as,
app.use(logicRoute)
app.use(storeResponseMiddleware)
Now, for all the responses storeResponseMiddleware will be called. you must call next() inside the route handlers.

Categories

Resources