Consider this example
#Scope(ScopeType.SESSION)
#Name("test")
#BypassInterceptors
public Class Test {
#Unwrap
public List<String> test() {
//do a long and major calculation and return the List
}
}
Then you have a view and you are getting your list
<h:selectOneMenu value="#{someBean.text}">
<s:selectItems value="#{test}"/>
</h:selectOneMenu>
Now in my opinion, because I have Scope session, the list should be cached, or the Seam manager component at least, so that it will run once, but then when you revisit the page in the same session, it should not run again, but when I re-enter the page the Unwrap method is yet again run.
So my question is, what is the difference between Session scope and say Event scope here?
To circumvent this I have manually cached the list in the session context and retrieve it from the context if it is present in the #Unwrap method
Seems like I have misunderstood the Manager component.
The #Unwrap is useful if you want to perform an action before the object is accessed. e.g. the SMPC uses #Unwrap to make sure it has joined the transaction every time.
It is actually the #Factory annotation that suits my needs, which will outject the return value.
Thus the scope of the component is still valid as normal Seam component scopes. Of course in that exact example, its not that useful as there are no fields.
#Unwrap differs from #Factory because it is evaluated each time it is requested. If you have a page which needs current time and this page request the current date three times as follows
#{currentDate}
#{currentDate}
#{currentDate}
Because the component which encapsulates currentDate defines an #Unwrap method, it is evaluated three times
If you have #Factory instead, it is just evaluated once
#{compon.someFactory}
#{compon.someFactory}
#{compon.someFactory}
Related
Is there possibility below this method causes memory leak in anyway.
android:onClick="#{(v) -> viewModel.showList(v)}
My understanding is that, view reference is passed to view model, view model then uses reference and set its content to the view. On the fragment destroy, associated viewBinder is also destroy, the whole screen is releases from the memory. Are there anyway passed view reference going to be hold in the View Model once fragment is destroyed? I don't think so.
Do you recommend to use this notation? Can you share your experience if this is possibility of memory leak?
It can be memory leak in given scenario:
Let's say you click on view and this method viewModel.showList(v) get invoked along with view reference passed to it.
Now imagine that you've global variable globalViewRef in ViewModel that stores reference to this view, for example:
class MyViewModel: ViewModel(){
lateinit var globalViewRef: View
fun showList(v: View){
globalViewRef = v // Storing view reference globally for future methods/purpose etc.
}
}
And your ViewModel is shared across fragments with activity context, in such scenario if configuration change happens your viewModel leaks global view object due to change of context.
So, things to take in mind:
Never store view/context globally in ViewModel class (Use it locally inside method only if necessary).
If there's something you need hardly to store globally then override onCleared() & clean up reference there as it is the last call on ViewModel when it's going to destroy state (Consider this when ViewModel is not being shared across activity context).
If you've both things covered then there's no memory leak in your case that I can find of.
Is there a cost to accessing a session value? Apart from the cost of accessing a (I presume) dictionary. Maybe a session deserialize every time it's being accessed.
For example, I've seen some people put the session value in a variable.
_sessionValue = CType(Session(SESSION_NAME), SomeClass)
_sessionValue.SomeFunction1()
_sessionValue.SomeFunction2()
And others create a property
Public ReadOnly Property SessionValue As SomeClass
Get
Return CType(Session(SESSION_NAME), SomeClass)
End Get
End Property
SessionValue.SomeFunction1()
SessionValue.SomeFunction2()
I wonder if there is a significant difference in speed between the two or if one is recommended from the other.
Couple of things here. First, those code samples are doing nothing more than casting the session object to a type. This would be done anyway in the code using the object. The benefit is that there is a page property that you can easily use in any method. The session object won't be read and cast as the type unless you make a call to the property.
You should decide for yourself if you want to use a private or public member. There isn't really any difference between the property and the member.
You can read up on making session state fast here.
For details on seralizing and deserializng the session objects check this older post.
I have an ASP.NET MVC application. I have come to an idea of generating autoincremented values to be used as unique element ids. The question is, how can I have and work with a global variable which should be there for the duration of a request (page generation) but no longer?
I thought of using TempData for this shared variable and then just delete this key when the page is done. But then, where in code to purge this TempData key? Obviously it has to be some very last piece of code where the page has been rendered already.
Any input is highly appreciated.
EDIT: I have a number of HTML helpers that can be called from various views and partial views, so declaring a variable on a page and passing it to each helper is obviously not a good solution. I wish to just use the helpers and know they all are getting unique ids behind the scenes.
Okay, I have googled a little bit and found a solution on ASP.NET forums.
http://forums.asp.net/t/1401685.aspx
Obviously, I can use the HttpContext.Current.Items collection to have my little static variable for the duration of a request.
If all you need is to store a number, the resources that would take to manage its lifestyle would take a lot more than just having a one static integer and always reusing it.
Do not bother deleting the key after each request. Just use a static (I think this is shared in visual basic) integer, use and increment it every time you need a unique value. Also take its mod with a ridiculously high number each time to make sure it will not be reused in a single request and it will never overflow.
Why don't you define your integer variable at the top of the page view file?
Use it throughout the view rendering execution and at the end of it you can easily leave it as is. You don't have to explicitly destroy anything. Your variables live for the duration of request only. IIS is stateless service (if you subtract Session, Cache and Application variables) so it doesn't really remember anything explicitly.
I would imagine you could use the Application_BeginRequest and Application_EndRequest methods in global.asax.cs; Note I can't double check the method names currently, but I think they are close.
You could create a member variable in your controller which would be regenerated for each request:
public class ItemController : Controller
{
private int _UniqueID = 0;
public ActionResult Index()
{
foreach (var item in items)
{
item.UniqueID = _UniqueID++;
}
// etc...
}
I'm currently building the client side of a Flex/PHP project using the Presentation Model pattern.
What I'm trying to achieve:
I currently have a view displaying non-editable information about a domain object called Node. Depending on if the Node is editable and the user has the right privileges, an additional view becomes available where it's possible to make changes to this object. Any changes made are only committed to the server once the user decides to "Save Changes". If changes are made to a NodeA and the user navigates away to a different NodeB without saving them, NodeA is reverted to its original state.
Design:
I have a PM for the info view holding a reference to the current Node. The PM for the edit view is extended from this info PM, adding methods to make changes to the wrapped Node object. Both PMs has the same Node reference injected into them and all fields in the info/edit views are bound to the Node via their PMs.
The problem:
When the user makes changes to NodeA but doesn't commit them, I can't seem to think of an elegant solution to revert back to the original state. Basically, what I've thought of so far is to hold separate value copies on the edit PM, either clone-creating a new Node reference or through an identical set of Node properties. Of these two the former seems like the better idea because the Node already houses domain logic, but I wonder whether creating clones of unique domain objects is a bad practice, even if it's used in a limited scope.
I handle similar cases by storing the original data in an XML property of the Value Object ("VO"), and reset all of the other property values when the VO is needed.
So, when it is first needed to be viewed, I go get the XML:
<Node>
<prop1>value</prop1>
<prop2>value</prop2>
<prop3>value</prop3>
<prop4>value</prop4>
</Node>
When I retrieve the XML, in my result handler, the first thing I do is create an instance of my VO, and set the XML property, and then call a public function in a separate class to set the VO's properties:
private function getNodeResultHandler(event:ResultEvent):void
{
var myNode:Node = new Node();
myNode.xmlData = new XML(event.result);
nodeUtils.setNodeProperties(myNode);
}
public class nodeUtils
{
public function setNodeProperties(node:Node):void
{
var nodeXmlData:XML = node.xmlData;
myNode.prop1 = nodeXmlData.prop1;
myNode.prop2 = nodeXmlData.prop2;
myNode.prop3 = nodeXmlData.prop3;
myNode.prop4 = nodeXmlData.prop4;
}
}
Then, any time you switch your view to edit mode, you call that same function to reset the properties to the values stored in the XML.
The only other thing you need to do is reset that XML any time the user commits changes to the VO. I usually handle this by passing back the VO's data in the same format on a Save and Get, and then saving the XML just as above.
I usually do this in a Cairngorm MVC application, so I have event/command chains to handle all of this, but you can put this functionality in any number of classes, or in the VO class itself, whichever is easiest for you to maintain.
Each view should have it's own instance of your Presentation Model class. Just maintain it in memory if the user has not saved it when moving to another view. Cloning accomplishes basically the same thing through a more convoluted process.
The background to this question is that I need to use some user session data in a (static) WebMethod. I have created a static property that references the data I need like so:
private static UserWebSession UserWebSession
{
get
{
return (UserWebSession)HttpContext.Current.Session["UserWebSession"];
}
}
I can then call this in my page's static WebMethod.
My question is, is this technique thread safe? Or will this property's value be updated with every new page request - in other words, it will return the UserWebSession for the user who most recently requested the page?
That's fine - HttpContext.Current is designed precisely for this sort of thing. You won't get a previous user's session.
It's dependent on the thread though (I believe) - so if you start any extra background threads, they won't be able to see the current context.
Also be aware that although this call is safe in terms of not getting the wrong context, the normal concurrency caveats apply when it comes to what you actually do with the context.
I don't know that a Page Method is able to access Session state. If it can, then you may be ok. I recall that access to Session state is serialized, so that only one request at a time can arrive for a given session.