Django: Class based view instantiated for each request, is it efficient? - django

From Django documentation:
While your class is instantiated for each request dispatched to it,
class attributes set through the as_view() entry point are configured
only once at the time your URLs are imported.
Will it not be inefficient to instantiate view per request considering heavy concurrent traffic ?

Beside the comment from jpmc26 I would guess its not a big problem. If you follow the workflow Django is doing from when a request is coming in until the response is rendered, there are way more steps involved which initiate objects. The class-based view is probably the least of the problem, assuming you didn't implement it to be blocking.

I'm not sure why you think memory would be an issue (if you had been talking about time taken, you might have had an argument, but see jpmc26's comment).
Python's memory allocation/deallocation is done by means of reference counting, not timed garbage collection. As soon as an object goes out of scope, assuming it has no circular references, it is destroyed. So if the server has enough memory to serve the request and allocate the object in the first place, there's no danger of it hanging around past its useful lifetime.

Related

Behavior of creating objects in ColdFusion

At one time I had a theory that instantiating objects on every request rather than having them reside in the Application scope was a huge memory hog. As my knowledge of ColdFusion has grown over the years, I don't think I really understood how CF deals with classes in the "black box" of the CF framework, so I'm going to ask this for community correction or confirmation.
I'm just going to throw out what I think is happening:
A CFC is compiled into a class, each method within that CFC is compiled into a class.
Those classes will reside in (PermGen) memory and can be written to disk based on CF administrator settings.
When a new object is created or template requested, the source code is hashed and compared to the hash stored with the compiled class.
If there is a match, it will use the compiled class in memory
If the compiled class doesn't exist, it will compile from source
If the compiled class exists, but the hash doesn't match, it will recompile.
As an aside, whenever you enable trusted cache, ColdFusion will no longer hash the source to check for differences and will continue to use the compiled class in memory.
Whenever you create a new object, you get a new pointer to the compiled class and its methods' classes and any runtime events occur in the pseudo-constructor. Edit: At this point, I'm referring to using createObject and having any "loose" code outside of functions run. When I say pointer, I mean the reference to memory allocated for the object's scopes (this, variables, function variables).
If you request an init, then the constructor runs. The memory consumed at this point is just your new reference and any variables set in the pseudo-constructor and constructor. You are not actually taking up memory for a copy of the entire class. Edit: For this step I'm referring to using the new operator or chaining your createObject().init() old school.
This eliminates a huge fallacy that I, personally, might have heard over the years that instantiating large objects in every request is a massive memory hog (due to having a copy of the class rather than just a reference). Please note that I am not in favor of this, the singleton pattern is amazing. I'm just trying to confirm what is going on under the hood to prevent chasing down red herrings in legacy code.
Edit: Thanks for the input everyone, this was a really helpful Q/A for me.
I've been developing CF for 14 years and I've never heard anyone claim that creating CFC instances on each request consumed memory due to class compilation. At the Java level, your CFML code is direct compiled to bytecode and stored as Java classes in memory and on disk. Java classes are not stored in the heap, but rather in the permanent generation which is not (usually) a collected memory space. You can create as many instances of that CFC and no more perm gen space will be used, however heap space will be allocated to store the instance data for that CFC for the duration of its existsance. Note, open source Railo does not use separate classes for methods.
Now, if you create a very large amount of CFC instances (or any variable) for that matter, that will create a lot of cruft in your heap's young generations. As long as hard references are not held after the request finishes, those objects will be cleared from the heap when the next minor garbage collection runs. This isn't necessarily a bad thing, but heap sizes and GC pauses should always be taken into account when performance tuning an application.
Now, there are reasons to persist CFC instances, either as a singleton pattern or for the duration of a session, request, etc. One reason is the overhead of actual object creation. This often involves disk I/O to check last modified times. Object creation has increased speed significantly since the old days, but is still pretty far behind native Java if you're going to be creating thousands of instances. The other main reason is for your objects to maintain state over the life of the application/session/request such as a shopping cart stored in session while the user shops.
And for completeness, I'll attempt to address your points categorically:
For Adobe CF yes, for Railo, methods are inner classes
Yes.
Actually, I don't believe there is any hashing involved. It's all based on the datetime last modified on the source file.
Yes, but again, no hashing-- it just skips the disk I/O to check the last modified datetime
I don't think "pointer" is the right term as that implies the Java classes actually live in the heap. CF uses a custom URL classloader to load the class for the template and then an INSTANCE of that class is created and stored in the heap. I can understand how this may be confusing as CFML has no concept of "class". Everything is simply an instance or doesn't exist at all. I'm not sure what you mean by "runtime events occur[ing] in the pseudo-constructor".
To be clear, the JAVA constructor already ran the instant you created the CFC. The CF constructor may be optional, but it has zero bearing on the memory consumed by the CFC instance. Again, I think you're getting unnecessarily hung up on the pseudo-constructor as well. That's just loose code inside the component that runs when it is created and has no bearing on memory allocated in the heap. The Java class is never copied, it is just the template for the instance.

django - why is the request.POST object immutable?

As the title asks, why did the Django guys decide to implement the request.POST object with a querydict (which, of course, in turn, makes the whole thing immutable?)
I know you can mutify it by making a copy of the post data
post = request.POST.copy()
but why do this? Surely it would be simpler just to allow the thing to be mutable anyway? Or is it being used for some other reason too which might cause issue?
It's a bit of a mystery, isn't it? Several superficially plausible theories turn out to be wrong on investigation:
So that the POST object doesn't have to implement mutation methods? No: the POST object belongs to the django.http.QueryDict class, which implements a full set of mutation methods including __setitem__, __delitem__, pop and clear. It implements immutability by checking a flag when you call one of the mutation methods. And when you call the copy method you get another QueryDict instance with the mutable flag turned on.
For performance improvement? No: the QueryDict class gains no performance benefit when the mutable flag is turned off.
So that the POST object can be used as a dictionary key? No: QueryDict objects are not hashable.
So that the POST data can be built lazily (without committing to read the whole response), as claimed here? I see no evidence of this in the code: as far as I can tell, the whole of the response is always read, either directly, or via MultiPartParser for multipart responses.
To protect you against programming errors? I've seen this claimed, but I've never seen a good explanation of what these errors are, and how immutability protects you against them.
In any case, POST is not always immutable: when the response is multipart, then POST is mutable. This seems to put the kibosh on most theories you might think of. (Unless this behaviour is an oversight.)
In summary, I can see no clear rationale in Django for the POST object to be immutable for non-multipart requests.
If the request was the result of a Django form submission, then it is reasonable for POST being immutable to ensure the integrity of the data between the form submission and the form validation. However, if the request was not sent via a Django form submission, then POST is mutable as there is no form validation.
You can always do something like this: (as per #leo-the-manic's comment)
# .....
mutable = request.POST._mutable
request.POST._mutable = True
request.POST['some_data'] = 'test data'
request.POST._mutable = mutable
# ......
Update:
Gareth Rees was right that point 1 & 3 were not valid in this case. Though I think point 2 and 4 are still valid, therefore I will leave theses here.
(I noticed that the request.POST object of both Pyramid(Pylon) and Django is some form of MultiDict. So perhaps it is a more common practice than making request.POST immutable.)
I can't speak for the Django guys, though it seems to me that it could because of some of these reasons:
Performence. immutable objects are "faster" over mutable ones in that they allow substantial optimizations. An object is immutable means that we can allocate space for it at creation time, and the space requirements are not changing. It also has things like copy efficiency and comparison efficiency because of it.
Edit: this is not the case for QueryDict as Gareth Rees pointed out.
In the case of request.POST, it seems no activity in the server side should need to alter the request's data. And hence immutable objects are more suited, not to mention they have substantial performence advantage.
Immutable objects can be used as dict keys, which I suppose could be very useful somewhere in Django..
Edit: my mistake, immutable does not directly imply hashable; hashable objects however, are typically immutable as well.
When you pass around request.POST (especially to third-party plugins and out), you can expect that this request object from the user will remain unchanged.
In some way these reasons are also generic answers to "immutable vs mutable?" question. I am certain there are much more design considerations than above in the Django case.
I like it being immutable by default.
As pointed out you can make it mutable if you need to but you must be explicit about it.
It is like 'I know that I can make my form debugging a nightmare but I know what I am doing now.'
I found this in a comment on Stack Answer https://stackoverflow.com/a/2339963
And it must be immutable so that it can be built lazily. The copy forces getting all the POST data. Until the copy, it may not all be fetched. Further, for a multi-threaded WSGI server to work reasonably well, it's helpful if this is immutable
Please note: multipart request are immutable since Django 1.11
https://github.com/django/django/blob/stable/1.11.x/django/http/multipartparser.py#L292
They were mutable in previous versions.

Notifying a class of another class' changes

Having the classes Container, Item and Property, the container shall be notified whenever a property in an item changes.
The container is the owner of the items and needs the information to properly manage them according to their properties.
I've thought of 2 options yet:
Observer pattern.
Proxy object.
The observer pattern seems to be too heavy for that task in my opinion. A proxy object could work out well, however in that case I'd violate the DRY principle, because I have to forward calls from the proxy to the actual object.
A requirement is that the details are hidden from the user. It's required that it's not needed to call some update_item() function or similar, i.e. giving the responsibility of informing the container to the user, which might lead to usage problems.
In such simple case I don't see a reason of using Observer. Since an Item can be only in one container at once I would just go with giving the Item a reference or pointer to the container it is placed in.
When some Property of the Item changes it as able to notify it's Container via that pointer
Observer pattern is useful in case you need to notify many objects.
EDIT
Making every simple thing using Interfaces and extremely clean design may also harm you. I think the quote from zen of Python explains good what i mean:
Special cases aren't special enough to break the rules. //make Interfaces
Although practicality beats purity. //but not everywhere
So you should a have balance between purity and practicality
You should use the pattern that is easiest to understand and maintain, and requires the least invention of specialized components. In the environment I work in (objective-C), the observer pattern is about as uncomplicated as it gets. It also offers flexibility when your notification requiements change.
Andrew's answer is event simpler - direct communication between objects does not requie the invention of a proxy or the overhead of notification handling. But it has less flexibility, should you need it in the future.
I'm not sure what "too heavy" means. Perhaps you can explain that.
As has been mentioned before, an Observer is pretty much overkill here, but the solution is pretty simple. You just need to "bubble up" the event.
When a property is changed, it notifies it's parent item.
When an item is changed (a side-affect from either a property changing, or something more integral to the item), it notifies it's container/parent).
When a container is notified, well, you're done. If containers can be nested then I guess it can raise an event to it's parent container if necessary.

Storing Coldfusion CFC instance in REQUEST scope, is it safe?

Is it safe to store a CFC object in the REQUEST scope to be accessed later? Right now, our sites load up navigation data at least twice, possibly three times if they use our breadcrumbs feature. Some times, this data can vary, however, most of the time, three separate calls end up being made to grab the same exact navigation data...
So, I was thinking after the first load, save the navigation data in the REQUEST scope in some sort of struct, and in subsequent calls, just check to see if that data is already there, and if so, just use what is stored rather than re-creating it again. I know this would be accessing a shared scope outside of a contained object, which is probably not good practice, but in the end could shave off half of our page load times...
I know it can be done, however, we have had problems with the server recently, some of it possibly being memory leaks from how we use/store certain things, so was wondering if this was safe to do...
Either the variables or request scope would be suitable for your purpose, however more advisable would be to modify the functions that require access to this variable to accept your cached variable as an argument. With regard to CFCs it could be passed in the init() method and stored for use by the methods within that CFC (assuming you initialise it)
By relying on a global variable (even one restricted to current request) you are potentially just causing difficulties for yourself down the line, which would be solved by ensuring the methods are more encapsulated.
As mentioned in my comments earlier, ColdFusion - When to use the "request" scope? is worth a quick read as it has relevant information in the answers.
Yes. The only request that has access to the REQUEST scope is the current request.

ASP.NET web services leak memory when (de)serializing disposable objects?

In the following two cases, if Customer is disposable (implementing IDisposable), I believe it will not be disposed by ASP.NET, potentially being the cause of a memory leak:
[WebMethod]
public Customer FetchCustomer(int id)
{
return new Customer(id);
}
[WebMethod]
public void SaveCustomer(Customer value)
{
// save it
}
This (alleged) flaw applies to any IDisposable object. So returning a DataSet from a ASP.NET web service, for example, will also result in a memory leak - the DataSet will not be disposed [EDIT: This post claims that Dispose on a DataSet does nothing, so maybe this isn't such a problem]
In my case, Customer opened a database connection which was cleaned up in Dispose - except Dispose was never called resulting in loads of unclosed database connections. I realise there a whole bunch of bad practices being followed here, but the point is that ASP.NET - the (de)serializer - is responsible for disposing these objects, so why doesn't it?
This is an issue I was aware of for a while, but never got to the bottom of. I'm hoping somebody can confirm what I have found, and perhaps explain if there is a way of dealing with it.
This is really a problem with your design, not with ASP.NET. The XmlSerializer it uses to serialize objects over SOAP doesn't know anything about the objects being serialized or whether or not they implement IDisposable. Moreover, it's not immediately apparent that they should be disposed, even if they do implement IDisposable; you might be returning a singleton instance, or an object in the cache.
Web services should accept and return message classes, AKA proxy classes, aka Data Transfer Objects, which are very simple, lightweight POCO classes without any real state or intelligence and especially no ownership of unmanaged resources.
You can use a tool like AutoMapper to quickly and easily map between your domain model classes like Customer (which apparently holds onto a database connection) and the DTOs that your web service uses.
There might be exceptions to this rule, but in most cases, if a function returns an IDisposable object to you, it's now your problem to Dispose it.
That's why you're seeing the "leak". Yes, in time the GC will clean it up when memory is needed, but until it does, potentially important resources remain locked/in-use.
So remember the rule: It's it's IDisposable, Dispose of it when done!
=)