OrchardCMS / Orchard

Orchard is a free, open source, community-focused Content Management System built on the ASP.NET MVC platform.
https://orchardproject.net
BSD 3-Clause "New" or "Revised" License
2.37k stars 1.12k forks source link

Session timing out? NullReferenceException in Orchard.Layouts.Controllers.ElementController.Update #7551

Open Thierry-S opened 7 years ago

Thierry-S commented 7 years ago

I think this is similar (or even identical) to "Orchard Content Pages" in https://github.com/OrchardCMS/Orchard/issues/7138

I have the same error

Oops. Something went wrong ... sorry An unhandled exception has occurred and the request was terminated. Please refresh the page. If the error persists, go back Object reference not set to an instance of an object. System.NullReferenceException: Object reference not set to an instance of an object. at Orchard.Layouts.Controllers.ElementController.Update(String session) at lambda_method(Closure , ControllerBase , Object[] ) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary'2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary'2 parameters) at System.Web.Mvc.Async.AsyncControllerActionInvoker.b39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.b3d() at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>cDisplayClass46.b3f() at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>cDisplayClass46.b3f() at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>cDisplayClass46.b3f()

I'm in the Content Editor, i'm editing a page, an HTML block, and clicked the </> icon to edit it. I can spend some time in there making my edits. When I click SAVE (in the dialog called "Edit HML") that's when I sometimes get the error, and loose all my changes (so I can't do the suggestion from #7138 to refresh the page and refresh my expired session).

To reproduce the problem, I bring up the Edit HTML box in a client web browser, then on my IIS, I recycle the Orchard App pool. Then I click SAVE. I get this error.

Now, I get this in normal usage, which is a problem. Users end up typing in MS Word, then copy/paste into Orchard because so many have lost their work.

My Orchard app pool has the default Idle Time-out (minutes) set to 20 minutes. My Event Log shows the WAS event 5186 "A worker process with process id of '5528' serving application pool 'OrchardAppPool' was shutdown due to inactivity. Application Pool timeout configuration was set to 20 minutes. A new worker process will be started when needed."

But I'm confident that sometimes, from within the Edit HTML popup dialog, I click things (make bold, insert bullet list...) so I am active, then click save and boom, I loose my work. I imagine if I click "insert media", since it does network requests against the server, it keeps alive my session.

A possible fix would be to only recycle the Orchard App pool after 600 minutes of inactivity (10 hours), to be on the safe side. But I would have thought there are better ways for Orchard to keep the session alive, some sort of Heartbeat, or a warning on the client side saying "your session will expire in X minutes, save your work"?

Thierry-S commented 7 years ago

Or could the app pool recycling frequency be changed in the web.config of the orchard folder itself? (rather than an administrator with rights to change iis configuration)

sebastienros commented 7 years ago

You can change the session timeout in the web.config.

sebastienros commented 7 years ago

Or you can add a piece of Javascript in the Layout editor that will ping the server every few minutes to keep the session open.

But maybe the layout module should not use sessions. I didn't know it was using it. @sfmskywalker is it?

paynecrl97 commented 7 years ago

@sebastienros yes, it does.

I've fixed this for a couple of clients by creating an implementation of IObjectStore (which is just a key value store) that uses ICacheService for storage and retrieval. This has the benefit of using the same storage mechanism as caching does (Redis, in-memory, or other).

I'd happily contribute this back, but it'll create a dependency on Orchard.Caching for Orchard.Layouts (or vice versa).

Another option would be to use ICacheManager, but this has the disadvantage of being in-memory, and so is not suited to sites running on multi node farms.

3rd option is to change the default implementation to use ICacheManager, and add a new feature to either Layouts or Caching that would switch to ICacheService when enabled.

If you let me know which you'd prefer, I'll look at raising the PR.

Thierry-S commented 7 years ago

@sebastienros : you talk about changing the session timeout in web.config, you mean the http session? Is it the http session that ends and causes the problem, rather than the http application ending? Ending the http app will also end all user's http sessions, so I could have misjudged the source of the problem. I'll have a play and reduce the http session to 1min to see if I can accurately reproduce the problem.

On a general point, as an end user (administrator) of a cms, it would be nice if I don't have to do any programming to use the software for what's it's intended for, so having a session timeout configuration box somewhere, or a session ping javascript, or whatever solution to warn me I'm about to loose my work, should be built in.

Thierry-S commented 7 years ago

Ok, I've misjudged the situation, just as @sebastienros said, it's the http Session ending that's causing my problem (not the app recycling). So I put this in my Orchard virtual foder web.config: <sessionState mode="InProc" timeout="1"/> and after 1min5s, clicked the SAVE button on the HTML edit popup, and got the Ooops error.

The default is 20mins, which seems long enough, but some users might keep edit boxes opened for much longer.

In addition, my Orchard virtual folder is under my main website. My main website has a feature to auto log out users if they are inactive and prevent loging from 2 computers at the same time. To implement this, we set the http session timeout to 2mins, and we have a javascript heartbeat every 1 minute for up to 20mins (so that if the user doesn't do anything for 21 minutes, the session is ended, or if they close the web browser). Anyway, this setting is inherited in my Orchard virtual folder, as it's NOT in the web.config by default. So I ended unwillingly with a 2min http session timeout in orchard, which is the source of my problem. My fix is of course to make this much longer in the web.config and overwrite the inherited value from the root website.

Problem remains, for a normal user (without my weird setup), the timeout is still 20mins and they'll get that error and loose their work if the edit window is opened for longer than 20mins. You might see this as an improvement rather than a bug.

sebastienros commented 7 years ago

Another option is to have an autosave feature in your case that would submit a draft automatically after some time of work (that would also keep the session open btw).

roballred commented 6 years ago

+1 for a feature that automatically saves after a period of time. We have been running into contributors losing data because of timeouts.

sebastienros commented 6 years ago

Or you can add a piece of Javascript in the Layout editor that will ping the server every few minutes to keep the session open.

Someone should do it, that's pretty easy and would solve the issue.