Best way to store data between two request - wcf

I need one a bit theoretical advice. Here is my situation : I have a search system, which returns a list of found items. But the user is allowed to display only particular amount of items on one page, so when his first request is sent to my WCF service, it gets the whole list, then tests if the list isn't longer then the ammount of items my user is allowed to get and if the list isn't longer, there is no problem and my service returns the whole list, but when it is, then there is problem. I need to let the user choose which page he wants to display, so I let the javascript know that the user should choose page and the "page number dialog" is shown and then user is sending the second request with page number. And based on this request the webservice selects relewant items and sends them back to user. So what I need to do is to store the whole list on the server between first and second request and I 'd appreciate any idehow to store it. I was thinking about session, but I don't know if it is possible to set timeout only to particular sesion (ex. Session["list"]), because the list is used only once and can have thousands of items, so I don't want to keep it on the server to long.
PS. I Can't use standart pagination, the scenario has to be exactly how is described above.
Thanks

This sounds like a classic use-case for memcached. It is a network based key-value store for storing temporary values. Unlike in-memory state, it can be used to share temporary cached values among servers (say you have multiple nodes), and it is a great way to save state across requests (avoiding the latency that would be caused by using cookies, which are transmitted to/from the server on each http request).
The basic approach is to create a unique ID for each request, and associate it with a particular (set of) memcached key for that user's requests. You then save this unique ID in a cookie (or similar mechanism).
A warning, though, the memory is volatile, so can be lost at any point. In practice, this is not frequent, and the memcached algorithm uses a LRU queue. More details http://code.google.com/p/memcached/wiki/NewOverview
http://memcached.org/
Memcached is an in-memory key-value store for small chunks of arbitrary data (strings, objects) from results of database calls, API calls, or page rendering.
I'm not a .net programmer, but there appear to be implementations:
http://code.google.com/p/memcached/wiki/Clients
.Net memcached client
https://sourceforge.net/projects/memcacheddotnet .Net 2.0 memcached
client
http://www.codeplex.com/EnyimMemcached Client developed in .NET 2.0
keeping performance and extensibility in mind. (Supports consistent
hashing.) http://www.codeplex.com/memcachedproviders BeIT Memcached
Client (optimized C# 2.0)
http://code.google.com/p/beitmemcached jehiah
http://jehiah.cz/projects/memcached-win32

Related

How to limit the number of outgoing web request per second?

Right now, I am working on an ASP.NET Core Web API that calls an external web service and uses the returned data in its own response. This is working fine.
However, I discovered that the external service is not as scalable as I would like to. Therefore, as discussed with the company providing this external service, the number of outgoing requests needs to be limited to one per second. I als use caching to reduce the number of outgoing requests but this has been shown to be not effective enough because (as logically) it only works when a lot of requests are the same so cache data can be reused.
I have been doing some investigation on rate limiting but the documented examples and types are far more complicated than what I need. This is not about partitions, tokens or concurrency. What I want is far more simple. Just 1 outgoing request per second and that´s all.
I am not that experienced when it comes to rate limiting. I just started reading the referred documentation and found out that there is a nice and professional package for it. But the examples are more complicated than what I need for the reasons explained. It is not about tokens or concurrency or so. It is the number of outgoing requests per second that needs to be limited.
Possibly, there is a way using the package System.Threading.RateLimiting in such a way that this is possible by applying the RateLimiter class correctly. Otherwise, I may need to write my own DelegateHandler implementation to do this. But there must be a straightforward way which people with experience in rate limiting can explain me.
So how to limit the number of outgoing web request per second?
In addition, what I want to prevent is a 429 or so in case of to many request. In such a situation, the process should just take more waiting time in order to complete so the number of outgoing requests is limited.

Handling Large Requests to API

Are there best practices for how to pass large lists between services? I see some recommendations to pass S3 file URLs between services if the payloads can be large, but that seems like a step backwards because if the data is in S3 then the client can't use the server's API schema to validate the request as easily as if the data were passed in a list.
I can't process the data in small batches because it all needs to be processed at once.
Example:
Service B has API 1.
API 1's job is to receive a list of cars and when all cars are received to take some action on each car. All cars need to be acted on, it's not OK to take the action on only some cars.
Service A wants to send Service B 400,000 cars to store in Service B's database.
Should Service B structure API 1's API so that it expects:
A list of cars
A URL for an S3 file that contains a list of cars
Something else
It hugely depends on what actual requirements and constraints are. Sending a big amount of data via API in one go is usually not a good idea due to multiple reasons (network interruptions, memory consumption, etc.). If you don't have transactional requirements - you can just send data in small batches and (re)design the API to support that. Potentially you should consider completely switching from synchronous calls via API to asynchronous ones for example using some messaging pipeline (using Kafka for example).

Is STATE of Client or Server depends on Information (In REST point of view)?

I am really getting confused with the word STATE in REST
What exactly state means in REST? Is that something a form based on the information of data?
State of the APPLICATION changes means what?
Please explain what exactly state means in REST with a simple example by using REST CLIENT REQUEST & REST SERVER RESPONSE.
Your primary authority for REST is Roy Fielding's dissertation, which defines the term.
The discussion of the Data View would likely be the best starting point:
An application's state is therefore defined by its pending requests, the topology of connected components (some of which may be filtering buffered data), the active requests on those connectors, the data flow of representations in response to those requests, and the processing of those representations as they are received by the user agent.
An application reaches a steady-state whenever it has no outstanding requests; i.e., it has no pending requests and all of the responses to its current set of requests have been completely received or received to the point where they can be treated as a representation data stream. For a browser application, this state corresponds to a "web page," including the primary representation and ancillary representations, such as in-line images, embedded applets, and style sheets. The significance of application steady-states is seen in their impact on both user-perceived performance and the burstiness of network request traffic.

Prevent Duplicates in Rest API

We have an API endpoint which accepts people.
During the call we check to ensure that the person PIN has not already been used, if so we reject the request with a 422 input error.
Recently a client complained about a duplicate PIN and we found that the API endpoint was being triggered by two different REST calls with duplicated PINs but not a duplicate body.
i.e.
{First Name: John, Last Name: Doe, PIN: 722}
{First Name: Jane, Last Name: Doe, PIN: 722}
As both come in within milliseconds of each other when the test is performed on the second record for the duplicate PIN it returns false as the first record has not yet been inserted into the DB and as a result continues to process the second record.
We have looked into a few options, such as unique constraints on the DB which do work but would require huge amounts of rework to bubble the error up to the REST API response. A huge risk on a thriving production APP.
There are around 5-6 different API calls that can modify the PIN collection in one guise or another and around 20-30 different APIs where this sort of problem exists (unique emails, unique item name etc) so I am not sure we can maintain lists for quick access.
Aside from the DB constraints are there any other options available to us that would be simpler to implement? Perhaps some obscure attribute on the .NET APIController class.
In my head at least I would like a request to be made, and subsequent requests to be queued. I am aware we can simply store the payload for processing later however on the basis the APIs are already being consumed this doesn't seem to be an option the queue would have to block the response.
Trying to Google this has been far from successful as everything assumes I am trying to decline duplicate complete bodies.
If you're basing the check on whether the PIN exists in the db, in theory you could have tens or hundreds of potential duplicates coming in on the REST API, all assuming the PIN is ok as the database is slow to say whether a PIN exists.
If you think of it as a pipeline:
client -> API -> PIN check from db -> ok -> insert in db
the PIN check from db is a bottleneck as it will most likely be slower than incoming REST calls. As you say, the solution is to enforce the uniqueness at the database level but if that's not practical, you could use a 'gateway' check instead. Basically a PIN cache that's fast to update/query and PINs are added to it once the request has been accepted for processing and before they're written to the database. So the pipeline becomes:
client -> API -> PIN check from cache -> ok -> write PIN to cache ->
insert in db
and the second request would end up as:
client -> API -> PIN check from cache -> exists -> fail
so the cache is keeping up with the requests, allowing the more leisurely database operations to continue with known clean data. You'd have to build the cache (from PINs in the database) on every service restart and only allow API calls once the cache is ready if it's a memory cache. Or you could use a disk cache. The downside is it duplicates all the PINs in your database but it's a compromise that lets you keep up with checking PINs in API calls.

how would I expose 200k+ records via an API?

what would be the best option for exposing 220k records to third party applications?
SF style 'bulk API' - independent of the standard API to maintain availability
server-side pagination
call back to a ftp generated file?
webhooks?
This bulk will have to happen once a day or so. ANY OTHER SUGGESTIONS WELCOME!
How are the 220k records being used?
Must serve it all at once
Not ideal for human consumers of this endpoint without special GUI considerations and communication.
A. I think that using a 'bulk API' would be marginally better than reading a file of the same data. (Not 100% sure on this.) Opening and interpreting a file might take a little bit more time than directly accessing data provided in an endpoint's response body.
Can send it in pieces
B. If only a small amount of data is needed at once, then server-side pagination should be used and allows the consumer to request new batches of data as desired. This reduces unnecessary server load by not sending data without it being specifically requested.
C. If all of it needs to be received during a user-session, then find a way to send the consumer partial information along the way. Often users can be temporarily satisfied with partial data while the rest loads, so update the client periodically with information as it arrives. Consider AJAX Long-Polling, HTML5 Server Sent Events (SSE), HTML5 Websockets as described here: What are Long-Polling, Websockets, Server-Sent Events (SSE) and Comet?. Tech stack details and third party requirements will likely limit your options. Make sure to communicate to users that the application is still working on the request until it is finished.
Can send less data
D. If the third party applications only need to show updated records, could a different endpoint be created for exposing this more manageable (hopefully) subset of records?
E. If the end-result is displaying this data in a user-centric application, then maybe a manageable amount of summary data could be sent instead? Are there user-centric applications that show 220k records at once, instead of fetching individual ones (or small batches)?
I would use a streaming API. This is an API that does a "select * from table" and then streams the results to the consumer. You do this using a for loop to fetch and output the records. This way you never use much memory and as long as you frequently flush the output the webserver will not close the connection and you will support any size of result set.
I know this works as I (shameless plug) wrote the mysql-crud-api that actually does this.