ATG dynamo droplet scopes - atg

Can anybody explain why ForEach droplet has global scope, but not request scope?
I mean what this feature give us in performance (real-world app with many users) in comparison if it has the request scope.

If a component has request scope, it means that an instance (object) of this component will be created (time and memory resources) each time the component is requested. The more often requested - the more time is needed to create an objects. The more user\requests at a time - the more objects at a time. Global scope component are created once and can be re-used by all requests and different users.
ForEach droplet is stateless, can be used by many different requests\users at a time, so there is no reason to make it request scope.

Global scope means that the component is created only once. Droplets should be stateless because it's easier to use and maintain them. In your particular case, there's no point making ForEach droplet request scope because we can pass a new parameter to iterate through each time we call the droplet. On the other hand Form handlers should have request or session scope because they are intended to process users request, e.g. login process, submitting an order.

Related

Global variable in golang restful api

We have an post rest api in golang created using net/http package and used gorilla/mux as request router and dispatcher. The api takes an object as input, lets say x and set it as a global variable and through its course of action the api uses values within this object and provides result.
Now everything was working fine until we found out that when multiple requests hits the api other request modifies the global object. For eg, let say I have sent request with x = 5 and before this request ends another request came in and set x = 10, which causes multiple result for first request one with x=5 and other with x=10.
My query is, can I set a global variable per request? I understand session seems a straight forward answer but is it correct since its a REST api and it should be stateless, also if it is correct how can I do it in golang? What should be used as unique key in session? Also, if session is not the way to go then what is correct approach?
One of the reasons the context package exists is to make it easy to pass request-scoped values, try it out. You will have to pass the context to your methods, but that seems to be a much better way than using some package level variable and a mutex for synchronization.
https://blog.golang.org/context

HTTP GET for 'background' job creation and acquiring

I'm designing API for jobs scheduler. There is one scheduler with some set of resources and DB tables for them. Also there are multiple 'workers' that request 'jobs' from scheduler. Worker can't create job it must only request it. Job must be calculated on the server side. Also job is a dynamic entity and calculated using multiple DB tables and time. There is no 'job' table.
In general this system is very similar to task queue. But without queue. I need a method for worker to request next task. That task should be calculated and assigned for this agent.
Is it OK to use GET verb to retrieve and 'lock' job for the specific worker?
In terms of resources this query does not modify anything. Only internal DB state is updated. For client it looks like fetching records one by one. It doesn't know about internal modifications.
In pure REST style I probably should define a job table and CRUD api for it. Then I would need to create some auxilary service to POST jobs to that table. Then each agent would list jobs using GET and then lock it using PATCH. That approach requires multiple potential retries due to race-conditions. (Job can be already locked by another agent). Also it looks a little bit complicated if I need to assign job to specific agent based on server side logic. In that case I need to implement some check logic on client side to iterate through jobs based on different responces.
This approach looks complicated.
Is it OK to use GET verb to retrieve and 'lock' job for the specific worker?
Maybe? But probably not.
The important thing to understand about GET is that it is safe
The purpose of distinguishing between safe and unsafe methods is to
allow automated retrieval processes (spiders) and cache performance
optimization (pre-fetching) to work without fear of causing harm. In
addition, it allows a user agent to apply appropriate constraints on
the automated use of unsafe methods when processing potentially
untrusted content.
If aggressive cache performance optimization would make a mess in your system, then GET is not the http method you want triggering that behavior.
If you were designing your client interactions around resources, then you would probably have something like a list of jobs assigned to a worker. Reading the current representation of that resource doesn't require that a server change it, so GET is completely appropriate. And of course the server could update that resource for its own reasons at any time.
Requests to modify that resource should not be safe. For instance, if the client is going to signal that some job was completed, that should be done via an unsafe method (POST/PUT/PATCH/DELETE/...)
I don't have such resource. It's an ephymeric resource which is spread across the tables. There is no DB table for that and there is no ID column to update that job. That's another question why I don't have such table but it's current requirement and limitation.
Fair enough, though the main lesson still stands.
Another way of thinking about it is to think about failure. The network is unreliable. In a distributed environment, the client cannot distinguish a lost request from a lost response. All it knows is that it didn't receive an acknowledgement for the request.
When you use GET, you are implicitly telling the client that it is safe (there's that word again) to resend the request. Not only that, but you are also implicitly telling any intermediate components that it is safe to repeat the request.
If there are no adverse effects to handling multiple copies of the same request, the GET is fine. But if processing multiple copies of the same request is expensive, then you should probably be using POST instead.
It's not required that the GET handler be safe -- the standard only describes the semantics of the messages; it doesn't constraint the implementation at all. But any loss of property incurred is properly understood to be the responsibility of the server.

Renewing instances in Autofac

I know that the entire context of this issue is a bit specific, but I'll try to do my best explaining it. I'm performing a quite big importation from one ecommerce platform to nopCommerce.
nopCommerce works with Autofac as dependency injection container. Importing one product to nopCommerce involves some queries over nopCommerce tables and finally an insertion to the products table. These steps are repeated a lot of times, and Entity Framework context gets bigger, as it has to track more and more entities and trying to detect changes and figure out how many objects has to persist.
What I want to do is, in every iteration of the loop, renew the context, so it only tracks the entities associated to the current iteration. Obviously I want to achieve this, trying to not modify (as much as possible) nopCommerce core. In the container configuration, it is explicitly set that the EF context instances are given per http request (something I want to avoid, as I need a new instance per iteration).
An easy way to do it would be:
foreach job in jobs
Eject all instances in container
service1 = Container.RequestInstance<SomeServiceINeed>
service2 = Container.RequestInstance<SomeServiceINeed2>
DoTheJob
The thing is, I don't know how to accomplish this with Autofac. I have been trying to create a new ContainerBuilder and update the existing one, but _context.GetHashCode will always return the same instance.
Any idea about the best way to do it?
EDIT:
As it was suggested in the comments, I've tried to get the instances inside a lifetime scope. Basically:
using (var lifeTime = EngineContext.Current.ContainerManager.Container.BeginLifetimeScope())
{
service1 = lifeTime.Resolve<SomeServiceINeed>();
service2= lifeTime.Resolve<SomeServiceINeed2>();
..............
}
But I get this exception:
No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in
which the instance was requested. This generally indicates that a component
registered as per-HTTP request is being requested by a SingleInstance() component
(or a similar scenario.) Under the web integration always request dependencies from
the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime,
never from the container itself.
The services I'm trying to resolve, obviously depends also on a lot of different repositories and other services that are already defined in the container wiring (app start). Some of them are configured as 'PerHttpRequest'.
Thanks a lot!

Passing values from request to all the layers below controller

If a Play controller retrieves a values from the Request (e.g. logged in user and his role) and those values need to be passed to all the layers down to controllers (e.g. service layer, DAO layer etc) what's the best way to create a "threadlocal" type of object, which can be used by any class in the Application to retrieve those "user" and "userRole" values for that particular request? I am trying to avoid adding implicit parameters to a bunch of methods and Play Cache doesn't look like an appropriate fit here. Also play's different scope (session, flash etc) wouldn't behave right given all the code is asynchronous. Controller methods are async, service methods returns Future etc. That "threadlocal" type of effect in an asynchronous environment is desired.
Alternatives that are not a good fit
These alternatives are probably not helpful, because they assume a global state accessible by all functions across the processing of a request:
Thread local storage is a technique that is helpful for applications that process the request in a single thread, and that block until a response is generated. Although it's possible to do this with Play Framework, it's usually not the optimal design, since Play's strengths are of more benefit for asynchronous, non-blocking applications.
Session and flash are meant to carry data across HTTP requests. They're not globally available to all classes in an application; it would be necessary to pass the modified request across function calls to retrieve them.
A cache could in theory be used to carry this information, but it would have to have a unique key for each request, and it would be necessary to pass this key in each function call. Additionally, it would be necessary to make sure the cache data is not at risk of being evicted while processing the request, not even when cache memory is full.
Alternatives that may be a good fit
Assuming the controller, possibly though the Action call, retrieves the security data (user, role, etc.), and that the controller only deals with validating the request and generating a response, delegating domain logic to a domain object (possibly a service object):
Using the call stack: Pass the security data to all functions that need it, through an implicit parameter. Although the question is about finding an alternative to doing that, this approach makes it explicit what is being sent to the called function, and which functions require this data, instead of resorting to state maintained elsewhere.
Using OOP: Pass the security data in the constructor of the domain object, and in the domain object's methods, retrieve the security data from the object's instance.
Using actors: Pass the security data in the message sent to the actor.
If a domain object's method calls a function that also needs the security data, the same pattern would be applied: either pass it as (a possibly implicit) parameter, through a constructor, or in a message.

Does Apache2::RequestUtil::pnotes shared variables between different requests?

The document says :
Share Perl variables between Perl HTTP handlers
Does it mean it shared variables between different requests?
Or only shares variables within ONE request?
The latter - the data is made available to all handlers involved in generating a response to a single request and then the data is discarded.