xQuery application scope variable? - xquery

Is there a way to declare a variable in the application scope. This variable should stay in the memory and serves all the requests without the need to create it for each request. Something like session, but it is not tied to a specific user.
What Im looking for is something similar to php APC cache.

Session fields provide one possibility; another possibility is server fields:
http://docs.marklogic.com/xdmp:set-server-field
A server field is available to all requests for the appserver on the host.

Since this is tagged "marklogic" I will provide a MarkLogic non-standards answer.
The standards based answer is 'no' or 'question out of scope' because XQuery doesnt define an 'application scope' ( beyond the excecution of a the top level module's statement -- which in some context could be called 'application scope' )
In MarkLogic there is a supported feature called 'Sessions';
For web applications that coresponds to what is usually called "Session".
Sessions are created by the first call to xdmp:login() (explicitly or implicitly by running in the HTTP Server using a supported authentication).
Session 'state' is created on the first write to a session field (explicitly via xdmp:set-session-field, or implicitly in some cases(*)).
https://docs.marklogic.com/xdmp:set-session-field
Session Fields are a map of name (xs:string) to item()*
They last as long as the session lasts (see notes on expiration in link above).
Note that Sessions that span multiple HTTP requests require that the client side participate via proper HTTP Cookie handling ( ML server has no ability nor attempts to to track requests after the socket is closed except via the HTTP Cookie mechanism.)
If you are using a modern browser you need to not disable cookies.
If you are using a modern Web Client library this will likely be done for you.
If you are using one MarkLogics published SDK's (java, node, xcc) it will be done for you.
If you are going through a load balancer, Level 3 router, gateway, proxy ... those may need to be configured for "HTTP Session Affinity" (based on the cookies) to guarantee that cookies are passed through unchanged and that the SessionID cookie is mapped to HTTP affinity.(**)
Note: IT devices vary greatly in their capabilities and terminology.
What is often called "Session Affinity" may not relate to cookies, or
the right cookies. These can often be configured to work correctly but may
require custom code or configurations.
(*) Session state can be created implicitly in some cases by creating a multi-statement transaction.
(**)
https://docs.marklogic.com/guide/node-dev/extensions

Related

In a classic ASP application, is it better to use a session or cookie for cross-page data persistence?

I have inherited a fix on a classic ASP application where we want to store some user session-specific data to persist across page loads/their session, and need a bit of a refresher.
In the past I have simply used Session variables - ie. Session("SomeVar") = SomeVal.
In IIS on the production box, I noticed that ASP / Session Properties / Enable Session State = false. Setting this to True allowed me to successfully begin using session variables.
I don't want to consume any more resources than necessary on the server. In the past, I believe that I was under the delusional misconception that session variables in classic ASP were stored on the client side. Revisiting this now - the data is retained on the server side.
The string I am saving is a GUID, for roughly 3000 connected clients.
What kind of server impact am I looking at if I implement this, and would using client-side cookies be a better option?
Lets analyse this a bit, a GUID takes about 40 characters as a string hence in Unicode thats 80 bytes, lets call it 100 bytes. 100 * 3000 = 300KB. Can server spare 300K for this? I think the server already in trouble if the answer were no.
However there are other impacts to enable session state. When sessions are enabled ASP adds its own cookie to the client which in size terms is probably equivalent to the one you would need if you were storing your GUID as cookie instead of in the session. Its worth noting that this session ID stored in the cookie uses an algorithm which some say is more predictable (I haven't got any evidence of that myself). Hence if you are using the GUID as some form of authorization then storing the GUID as cookie directly may be better.
There is a further significant change that happens when Session state is enabled. ASP requests from a client must be processed serially, the server will not process multiple requests from the same client in parallel. This is because the Session object is single threaded and since each request from a client needs access to it the requests cannot be processed at the same time.
That last point could have significant impact on the existing behaviour and performance that a client sees especially if AJAX techniques, multiple IFrames or other techniques which result in simultaneous ASP requests being sent to the server are being used.
Hence for the requirement you have my choice would be to store the GUID in a cookie and leave session state turned off.
Multiple servers/server farm? If so you might run into trouble using Session if you load balancer is not set to be "sticky" and send you to the same server each time. Can me a real headache to debug so becareful.

ASP.NET application to serve multiple requests from a single process

I am currently debugging some issue about this.
We have a ASP.NET web application and I am debugging on Cassini. When I tried to use IE and send out the request to the server, some time (e.g. in about 20minutes) is needed to process and then send out the response.
In case of multi-tab IE, I tried to send out the requests in different tab at about the same time to the same server but the response is handled only after the one of the response is sent out.
If a new instance of IE is started and the requests are sent out in these different instances, the server can process and send out the response almost simultaneously. After doing some research I found that IIS express may solve my problem, but I cannot. Anyone has experienced similar problem or have I missed out some really important things to check with first?
Thank you for your help.
This is primarily due to ASP.net's session state variable and the fact that only one request at a time may have R/W access to a particular session (as determined by the SessionID cookie).
Any additional requests requiring any form of session access (since Read/Write is the default) will be blocked until the previous request has been completed.
Based on the following links:
http://johnculviner.com/asp-net-concurrent-ajax-requests-and-session-state-blocking/
https://msdn.microsoft.com/en-us/library/ms178581.aspx?f=255&MSPPError=-2147217396
I think that you miss the point that the session is lock all request leaving only one per time to run.
Read about that and why:
Replacing ASP.Net's session entirely
Also : Web app blocked while processing another web app on sharing same session
The reason is that Sessions in ASP.NET are not thread safe. Therefore ASP.NET serializes access to requests from the same session.
If you have a multi-tab IE then your tabs share one session. The first request is executed right off and the other ones are queued. If you have different instances then each of them creates a new session and therefore the request are executed in parallel.

Strategy for developing a multi function asp.net web application

I'm about to start a new project and want some advice on how to implement.
I need a web application which contains a booking module for reserving timeslots, and a time management module which will enable employees to clock in / clock out.
If I am writing an update to the time managment module, I don't want to disrupt the booking engine availability by releasing a new solution containing both modules.
to make things more difficult, there is some shared functionality like common users, roles and security.
Here's a suggestion I've gotten, which sounds a bit cruddy, but may be functional.
Write a 'container' web application which consists of basically a frame, and authentication / security features. This then has links which, will load the 2 independantly built and released web applications into the frame.
I can see that say, if I wanted to update the time management module, I would only need to build and release this separately, and the rest of the solution would be 'untouched'
Any better alternatives?
Unless I am missing something, if you run ASPX.net (v2, 3, whatever) you can replace the ASPX files (including any CLASS Files) on the fly and the WEB SERVER will automagically "do the right thing."
So if you wrap your "modules" in classes, you can replace those files on a whim without harming the functionality of other classes (not modified.)
As I re-read this am I getting convinced that I am misunderstanding your goal...
Sounds like you what you want is to have some thing along the lines of the Composite Application Block but for a web application (the CAB is for a smart client application).
One of the main things you would want to do is reduce and abstract the coupling between the modules as much as possible.
Keeping the session in the database would go a long way help your ability to dynamically load modules into the application.
This would allow you to have the time management in one server and the booking engine in another. When you update the functionality of one you simply update one server while the other keeps on serving the user.
Add two class library to your web application. one for "booking module" and one for "time management" module.
After compiling you will have one DLL for each module and put them in bin folder of web app (Visual Studio will do) then you can replace them separately when you need.
Maybe you know this already :
Sessions are the heart of problems in web if misunderstood.
Http is a connection-less protocol which means both sides of connection don't care about the flow of the communication. Simply a request has a single response. Without tracking a client how web applications can work ? assume we login to Yahoo mail. Single request (filled login page) is sent to server and a single response (inbox page) returns, then what if we want to see "Draft" folder ?
To inspire state to HTTP a simple solution added which we know as "cookies".
cookies are simple texts send with each request to a specified server. So on login page Yahoo server sends the response with some other text (cookie) which forces client (browser) to remember it and sent with every new request. This way Yahoo server (web application) can keep track of sequence of requests. This is why we should not simply close the browser window when we are done with yahoo and should logout. With logout yahoo server will forget about that cookie and any subsequent requests with that cookie are not accepted. So because Yahoo can't find out we closed the browser "connectionless" is a good name.
How asp.net handle this ?
simply asp.net uses a "session cookie" for any new request (requests without cookie) and let's you put your variables in "Session" object on server side. As long as we are at the same application we can use same session variables. What asp.net is doing behind is creating a table for "session Id" cookies and you "session variables". This is transparent to asp.net programmer. We just simply put a value in a session variable like this : session("Age") = 19; and read it when we need. ASP.NET take care of the rest with session cookies this way: you create a session variable (here "Age") so asp.net should track of this request; whatever is the response, asp.net adds a "session cookie" to it. "Session cookie" is a unique text which should be send by that client on consequent request till it expires (usually 20 minutes in asp.net). Use Firefox with "web developer" add-on to see and manipulate cookies.
Related concepts: session cookies vs permanent cookies, cookie properties (domain, expiration date, ...)
how server deals with cookies (keeping in memory, storing in database, ...)

How should I create cookie through flex/coldfusion that is readable by another template?

Inside a flex app, I have a user login. The login calls a ColdFusion function as a remote object which authenticates the user and, if applicable, returns their id and access level.
This works fine, but now I'm at the point where I want to also create a cookie for another ColdFusion template (called from fileReference.upload()) to be able to access later.
I have tried several different methods for creating the cookie -- cfcookie, creating a cookie with JavaScript inside the ColdFusion function, and creating the cookie with JavaScript with an external interface once the coldfusion function returns to the flex result handler. All of these have been tried with a plethora of options regarding expiration, path, and domain tags.
Any of these seems to work for cookie creation. Cookies show up in listings for my domain in Chrome as well as in a Firefox add-on 'View Cookies 1.9.2' that I've installed just for this purpose. Yet, still, none of these cookies seem to be readable by my upload.cfm when it is called later.
The upload.cfm, once called by a file upload request, sends the user id along with the file. From here, it should be a simple comparison between the id sent with the file and the id from the cookie. So far, the upload.cfm template has been unable to find the cookie (with any of the creation methods) looking at the obvious #cookie.name# or even #name#.
I'd appreciate any insight into why this is occurring, or perhaps an alternative method to the security I'm attempting to implement.
Thanks for reading,
-cs
Have you done most/all of your testing in a browser other than Internet Explorer?
Unfortunately, there is a bug in the Flash player [login required], which can be summarized as:
(In browsers other than Internet Explorer) The flash player uses a different network stack than the browser, and therefore...
Requests made by the flash player have a different server-side session than, for example, the request for the page that embeds the flash player.
This causes a situation whereby session variables set by the page are not (easily, by default) available to remote requests made by the flash player on the page.
CFID and CFTOKEN are set as cookies as well as stored in the session.urlToken variable. (JSessionId is included as well, if you're using Java session management).
I'm not positive, but I think this may be the root of your problem.
I believe that if you pass the CFID and CFTOKEN (and JSessionId) values to your Flex application as FlashVars, and then include them in the remote requests to the server, that the cookies you're setting will be available to later remote requests by flash (i.e. your upload).

asp.net, stateserver, NLB, session lost

1st post on stackoverflow, hope to have great feedback :)
I'm currently trying to load balance our web site. We have set up a 2 cluster NLB on windows server 2003 with IIS 6.
While testing the setup, I found that sometimes, our session is lost. A day and a half later, here's the result:
Yes, our machine.config both have the same encryption/decryption key.
Yes, the id in iis metabase.xml are the same for both machine. Actually, the entire file are the same, except for "AdminACL".
Both web application are set with "StateServer" and both pointing at the same machine.
From that point, searching on google gives less information and possible solutions.
From what I know, there's no particular pattern that cause this problem. It just happen once in a while.
While trying to find the problem, I've seen that a request sent the asp session id cookie to the server, but the server didn't map it to the user session.
So the request number x was sent from the client, with the cookie, session was mapped, and everything went smoothly.
The request number x+1 was sent from the client, with the cookie, but session was not found.
Both request were made on the same machine in the NLB.
Here's a snippet of the asp trace.axd:
1st request:
Request Details
Session Id: j2ffvy45updpc52uhw1mbg55 Request Type: GET
Time of Request: 11/26/2008 2:58:06 PM Status Code: 200
Request Encoding: Unicode (UTF-8) Response Encoding: Unicode (UTF-8)
Request Cookies Collection
Name Value Size
ASP.NET_SessionId j2ffvy45updpc52uhw1mbg55 42
AID 22 9
Response Cookies Collection
Name Value Size
Headers Collection
Name Value
Cookie ASP.NET_SessionId=j2ffvy45updpc52uhw1mbg55; AID=22
2nd Request:
Request Details
Session Id: Request Type: POST
Time of Request: 11/26/2008 2:58:08 PM Status Code:
Request Encoding: Unicode (UTF-8) Response Encoding:
Request Cookies Collection
Name Value Size
Response Cookies Collection
Name Value Size
Headers Collection
Name Value
Cookie ASP.NET_SessionId=j2ffvy45updpc52uhw1mbg55; AID=22
As you can see in the 2nd request, the cookie is sent from the client, but asp seems to never add the cookies in it's "Request Cookies Collection". I think that's why it doesn't find the session.
So why the cookie is not mapped to the session? Is that the problem? Is the problem elsewhere?
Feel free to ask any clarifications.
Thank you all for your feedback.
JF
I finally found the answer to my problem. It's origin are within the application code (like 99% of a programmer's 3rd party tools 'bugs'). I decided to post it anyway in case someone is in a similar scenario.
This code was part of WebServiceRequester class. The web service requester class was instanciated when session was created and it is saved in session. During creation, we initalizate the member 'm_webServiceURL', and this member is saved in session after. At which value was this member initialize was depending on a setting on the local machine.
The important part is the following:
WebServiceRequester class contains a WebService objects.
WebService objects can't be saved in session, they are not serializable in asp. The property had the [NonSerialized] attribute on it. So everytime we accessed the 'WebService' property of the object for the first during a page life cycle, we had to create a new one, and assigning ot it the url 'm_webServiceURL' which was saved in session.
So you see, new webservice object, on possibly a different machine, meaning a different setting on each machine.
so here's what happened:
box 29 was set to access Web Service at localhost
box 30 was set to access Web Service as 192.168.253.29.
Technically, they are both set on the same machine. But here's a scenario:
login on box 29. m_webServiceURL is set to localhost in session.
[some request on box 29 here]
NLB balancing bring us on box 30.
box 30 loads it's session, create a new webservice obect with localhost as the web service address.
box 30 made the request to the wrong web service leading to a Session Expired exception.
One of the problem during the debug, was that the local communication were not recorded with the network monitor.
What lead me on the trace, was that we never had an exception logged on the box 29 log trace, as it should have.
Thanks for you suggestions everyone, it was really appreciated.
Have a good day.
JF
Not strictly an answer to your question, but have you tried it using a sql server based session store? (Search on MSDN for the permanent script rather than the temp script that's provided with asp.net)
I've heard "bad things" about the executable session service, and consequently have not used it. Never had any problems web farming with the sql server based solution though.
Sorry it's not strictly an answer to your problem, but it should either (a) fix it, or (b) narrow it down significantly.
Well, if you're using visual studio, you could at least test it with the MSDE (the cut down version of SQL Server that comes with Visual Studio)...
It might help rule out state server problems...
Using the database approach has its own issues. I think you should be able to use your preferred approach.
Perhaps this session troubleshooting article would help?
Or "Troubleshooting Session Related Issues in ASP.NET"
Or "Troubleshooting Expired ASP.NET Session State and Your Options"
I'll be lame and re-iterate the proposal of MS SQL Server. Install SQL Server Express which is completeley free including for commercial use and it has only these 3 drawbacks which shouldn't be a problem for you in this stage :
Max 4GB size database
Max 1 CPU Core used
Max 1GB RAM used
A few points to take into consideration:
What's the load on your website? State Server has the tendency to crash when facing a large number of concurrent hits. We're only using it in scenarios where we have a really small number of users (in the 10's, mostly backend systems). Whenever we tried using it in production for sites serving 1000's of users daily, it would crash leading to loss of session data.
On one of the production environments we manage, we're using MSSQL 2005 Express to manage the sessions, the site has 10K+ users a day and 200K+ pages a day. This is a recommended approach in case session is a must and tightly coupled into your application.
If you're about to user MSSQL Express as your state DB, remember that it doesn't come with SQL Server Agent meaning there's no tasks scheduler running in the background and cleaning your expired sessions. I'd recommend finding a scheduler and running the clean expired sessions stored procedure periodically.
Good luck
Instead of messing around with SQL, send your tests directly into one of your IIS nodes to see if you still get the same issue. I'm sure if your only doing a small number of tests StateServer won't be the issue.
Try setting the domain name of the asp.net_sessionid through code to ".yourdomain.com".
By default the ASP.net_SessionID cookie domain name is set to the full application path. So, this may be one of the reason why the cookie is not travelling.
E.g.
Request.Cookies["ASP.NET_SessionId"].Domain = ".yourdomain.com".
Remember the first "." is important in the domain name.
You could do this in the HttpModule in the AcquireRequestState event.

Resources