Suppose you have a web application and you want to user to execute a particular action (e.g., answering a quiz question) within a specific time limit. What is the best way to enforce the time limit? I can think of two, with pros and cons:
client-side enforcement: works but susceptible to tampering
server-side enforcement: cannot be tampered with but may cause problems due to latency between server and client
any thoughts?
I would suggest client side enforcement, backed by server side sanity check. You could allow for latencies up to 30 seconds, or some other reasonable value on the server side, and declare client side tampering if the difference is too large.
Of course, this will allow for client side tampering, but only up to a certain amount of time that you allow for.
After writing the comment below, I thought of the following: you cannot trust the client's javascript to ping your server on page load for latency calculation - it is trivial to hijack it. But I don't know how I would cheat a redirect response. Prior to starting the test, you could take a time stamp and return a redirect response. Then you can calculate the latency on the server side on the redirected page. You could even do it a few times to get an average. I don't know how hard it would be to delay serving the redirect page request, but it may provide an extra layer of protection. Also it may allow you to give more realistic latency bounds.
Related
I've been traveling for the last couple weeks and have found a issue with the method that Ajax uses to construct a website. I understand that the webpage requesting only the pieces it needs is the most efficient method for the servers but when working in an environment where signal comes and goes or is being throttled by a provider, most websites running on this model become completely unresponsive and turn every interaction into a several minute wait.
In situations where the bandwidth is limited, the best performance generally comes from websites that have all of their content on one single page that is constructed for the user before it is sent. I understand that this is not the restful way but I was wondering if there was a middle ground to this solution.
Is there a way to batch many different AJAX calls where the user would only be sending one large call to the server which then the server would compile everything that is listed and then returns it in one heap? Or is this something that hasn't been formed into a standard yet and a custom server architecture would end up needing to do?
In a situation where bandwidth is extremely limited, everything you will try to do will be a pain.
Yes, in this scenario, frequently opening connections to the server through multiple requests (which is very typical of ajax single page applications) will make the experience worst than opening one single connection to the server.
However, you need to ask yourself if you want your web application to cater to clients with fast connections or to cater to clients with slow connections and design your web application accordingly. If you make it only to accommodate slow clients then the user experience for those with faster connections will suffer and vice versa.
You could also decide to cater to both audiences by creating a version for each but it's a lot of extra work
I have no idea what your web application does. But if it's to simply "view" data then perhaps you can get away with loading all the data from the start. However, if your web application contains a lot of data manipulation features then you have no choice, stick with Ajax and get a better internet connection.
If you want to batch your requests then your web application needs to be designed that way which would allow you to do everything you need to do on the client side before clicking on a "save" button that will gather all the changes you made and send it all in 1 request.
You should always build your web application according to your client's situation. If you're traveling a lot then that might be strictly your problem and won't ever be your client's problem. In this case, stick with ajax and get a better internet connection.
If the client is yourself then heck you could do whatever you want to ease your pain including loading everything from the get go.
Unfortunately there's no magic solution.
Hope it helps!
How to implement dynamically updating vote count similar to quora:- Whenever a user upvotes an answer its reflected automatically for every one who is viewing that page.
I am looking for an answer that address following:
Do we have to keep polling for upvote counts for every answer, If yes
then how to manage the server load arising because of so many users
polling for upvotes.
Or to use websockits/push notifications, how scalable are these?
How to store the upvote/downvote count in databases/inmemory to support this. How do they control the number of read/writes. My backend database is mysql
The answer I am looking for may not be exactly how quora is doing it, but may be how this can be done using available opensource technologies.
It's not the back-end system details that you need to worry about but the front end. Having connection being open all the time is impractical at any real scale. Instead you want the opposite - to be able to serve and close connection from back-end as fast as you can.
Websockets is a sexy technology, but again, in real world there are issues with proxies, if you are developing something that should work on a variety of screens (desktop, tablet, mobile) it might became a concern to you. Even good-old long polls might not work through firewalls and proxies.
Here is a good news: I think
"keep polling for upvote counts for every answer"
is a totally good solution in this case. Consider the following:
your use-case does not need any real real-time updates. There is little harm to see the counter updated a bit later
for very popular topics you would like to squash multiple up-votes/down-votes into one anyway
most of the topics will see no up-vote/down-vote traffic at all for days/weeks, so keeping a connection open, waiting for an event that never comes is a waste
most of the user will never up-vote/down-vote that just came to read a topic, so your read/write ration of topics stats will be greatly skewed toward reads
network latencies varies hugely across clients, you will see horrible transfer rates for a 100B http responses, while this sluggish client is fetching his response byte-by-byte your precious server connection and what is more importantly - thread on a back end server is busy
Here is what I'd start with:
have browsers periodically poll for a new topic stat, after the main page loads
keep your MySQL, keep counters there. Every time there is an up/down vote update the DB
put Memcached in front of the DB as a write-through cache i.e. every time there is an up/down vote update cache, then update DB. Set explicit expire time for a counter there to be 10-15 minutes . Every time counter is updated expire time is prolongated automatically.
design these polling http calls to be cacheable by http proxies, set expire and ttl http headers to be 60 sec
put a reverse proxy(Varnish, nginx) in front of your front end servers, have this proxy do the caching of the said polling calls. These takes care of the second level cache and help free up backend servers threads quicker, see network latencies concern above
set-up your reverse proxy component to talk to memcached servers directly without making a call to the backend server, yes if your can do it with both Varnish and nginx.
there is no fancy schema for storing such data, it's a simple inc()/dec() operation in memcached, note that it's safe from the race condition point of view. It's also a safe atomic operation in MySQL UPDATE table SET field = field + 1 WHERE [...]
Aggressive multi level caching covers your read path: in Memcached and in all http caches along the way, note that these http poll requests will be cached on the edges as well.
To take care of the long tail of unpopular topic - make http ttl for such responses reverse proportional to popularity.
A read request will only infrequently gets to the front end server, when http cache expired and memcached does not have it either. If that is still a problem, add memecached servers and increase expire time in memcached across the board.
After you done with that you have all the reads taken care of. The only problem you might still have, depending on the scale, is high rate of writes i.e. flow of up/down votes. This is where your single MySQL instance might start showing some lags. Fear not - proceed along the old beaten path of sharding your instances, or adding a NoSQL storage just for counters.
Do not use any messaging system unless absolutely necessary or you want an excuse to play with it.
Websockets, Server Sent Events (I think that's what you meant by 'push notifications') and AJAX long polling have the same drawback - they keep underlying TCP connection open for a long time.
So the question is how many open TCP connections can a server handle.
Basically, it depends on its OS, number of file descriptors (a config parameter) and available memory (each open connection reserves a read/write buffers).
Here's more on that.
We once tested a possibility to keep 1 million websocket connections open on a single server (Windows 7 x64 with 16Gb of RAM, JVM 1.7 with 8Gb of heap, using Undertow beta to serve Web requests).
Surprisingly, the hardest part was to generate the load on the server )
It managed to hold 1M. But again the server didn't do something useful, just received requests, went through protocol upgrade and kept those connections open.
There was also some number of lost connections, for whatever reason. We didn't investigate. But in production you would also have to ping the server and handle reconnection.
Apart from that, Websockets seem like an overkill here, SSE still aren't widely adopted.
So I would go with good old AJAX polling, but optimize it as much as possible.
Works everywhere, simple to implement and tweak, no reliance on an external system (I had bad experience with that several times), possibilities for optimization.
For instance, you could group updates for all open articles in a single browser, or adjust update interval according to how popular the article is.
After all it doesn't seem like you need real-time notifications here.
sounds like you might be able to use a messaging system like Kafka, or RabbitMQ, or ActiveMQ. Your front end would sent votes to a message channel and receive them with a listener, and you could have a server side piece persist the votes to the db periodically.
You could also accomplish your task by polling your database, and by incre/decre menting a number related to a post via a stored proc... there are a bunch of options here and it depends on how much concurrency you may be facing.
I have a text box in my application which allows a user to select a location with the help of UI autocomplete. There are around 10,000 valid locations out of which the user must select one. There are two implementations for the autocomplete functionality:
Fetch the list of locations when the page loads for the first time and iterate over the array to find matching items on every keystroke in javascript
Make ajax requests on every keystroke as searching in MySQL(the db being used) is much faster?
Performance wise, which one is better?
An initial test shows that loading the data at once is the better approach from a performance point of view. However, this test was done on a MBP where JavaScipt processing is quite fast. I'm not sure whether this technique is the better one for machines with low processing power like lower end android phones, old systems etc.
Your question revolves around which is quicker, processing over 10,000 rows in the browser, or sending a request to a remote server to return the smaller result set. An interesting problem that depends on context and environment at runtime. Sending to the remote server incurs network delay mostly, with small amounts of server overhead.
So you have two variables in the performance equation, processing speed of the client and network latency. There is also a third variable, volume of data, but this is constant 10k in your question.
If both client browser and network are fast, use whatever you prefer.
If the network is faster, use the remote server approach, although be careful not to overload the server with thousands of little requests.
If the client is faster, probably use the local approach. (see below)
If both are slow, then you probably need to chose either, or spend lots of time and effort optimizing this.
Both clients slow can easily happen, my phone browser on 3G falls into this category, network latency for a random Ajax request is around 200mS, and it performs poorly for some JavaScript too.
As user perceieved performance is all that really matters, you could preload the first N values for each letter as variables in the initial page load, then use these for the first keystroke results, this buys you a few mS.
If you go with the server approach, you can always send requested result AND a few values for each of the next keystroke. This overlaps what users see and makes it appear snappier on slow networks. Eg
Client --> request 'ch'
Server responds with a few result for each potential next letter
'cha' = ...
'chb' = ...
Etc
This of course requires some specialized javascript to alternate between Ajax requests and using cached results from previous requests to prefill the selection.
If you are going with the local client searching through all 10k records, then make sure the server returns the records in sorted order. If your autocomplete scanning is able to use 'starting with' selection rather than 'contains' (eg typing RO will match Rotorua but not Paeroa) then you can greatly reduce processing time by using http://en.wikipedia.org/wiki/Binary_search_algorithm techniques, and I'm sure there are lots of SO answers on this area.
If there is no advantage for querying the backend every time, don't do it.
What could be an advantage of querying the backend all the time? If the amount of returned data for the initial call is to heavy (bandwidth, javascript processing time to prepare it, time at all), the partial request every time could be the smarter option.
I'm trying to wrap my head around oauth2 and am comparing the server and client side flows. To me the server side flow sounds much more simpler - the user authorizes once and then everything remains on the server (converting the code to an access token, requests to the remote api, etc).
So, why would someone want to use the client-side flow?
One possible answer to that might be to reduce server traffic. Does anyone have any evidence that client-side reduces a significant amount of traffic from the server?
I think that it would be unlikely for approvals and access token grants to make up any sort of significant fraction of a server's traffic load unless it's implemented in a very obscure way. One might use the client-side flow if the application is very javascript-centric and has no other reason to contact a web server specifically for its service. For example, you could imagine some browser extension written in javascript that uses OAuth 2 to request someone's favorite YouTube videos, Facebook friends, or some other data, and display it to the user in some fashion. It may not make sense to dedicate a web server for serving those grants if it would perform no other function for the application.
I'm looking at implementing a live voting system on my website. The website provides a live stream, and I'd like to be able to prompt viewers to select an answer during a vote initiated by the caster. I can understand how to store the data in a mySQL database, and how to process the answers. However:
How would I initially start the vote on the client-side and display it? Should a script be running every few seconds on the page, checking another page to see if a question is available for the user?
Are there any existing examples of a real-time polling system such as what I'm looking at implementing?
You would have to query the server for a new question every few seconds.
The alternative is to hold the connection open until the server sends more data or it times out, which just reduces (but does not eliminate) the server hits. I think it is called "long polling". http://en.wikipedia.org/wiki/Push_technology
You will have to originate the connection from the client-side. The simplest solution is to have the page make an AJAX request every second or so. Web pages don't have to return immediately (they can take 30 seconds or more before responding without the connection timing out). This, opening one connection which doesn't respond until it has something to say, is "long-polling".
You could use setTimeout in JavaScript to make AJAX requests each few seconds to check whether there are new questions.
Yes, long polling might be better, but I'm sure it's a bit more complex. So if you are up to the job, go ahead and use it!
Here's a bit more info on the topic:
http://www.webdevelopmentbits.com/avoiding-long-polling