Using sessions in Espresso Framework - ruby

good progress so far.
got all controllers and actions up and running in matter of minutes.
However not sure how make sessions work.
trying:
class Cart
session :memory
# my actions
end
but it fails with an error that say to use sessions at app level.
how that? where is that app level?

I guess you are starting the app like this:
Cart.run
it is a good one unless you need to add some setup to your app.
creating app is as easy as:
app = EApp.new :automount
app.run
and if you have some setup for the app, use a block at initialization:
app = EApp.new :automount do
session :memory
end
app.run
Please note the first argument - :automount - it instructs the app to search for controllers and mount them automatically.
If you want to mount your controllers manually, omit first argument:
app = EApp.new do
session :memory
end
app.mount Cart
app.run

Related

How to force loading the current version of an offline-able web app?

I'm doing a tiny offline-able web app / PWA. It's meant to be opened from a home screen icon and mimic a regular app by loading entirely from a cache when offline.
The app is written using Vue and to accomplish the above I'm just using their PWA template and whatever it generates. To the best of my knowledge what this does is set up workbox using the GenerateSW plugin to precache everything in the Webpack build, and registers it using register-service-worker. That is, I have fairly little control out of the box over the fine details, it's meant to be a turnkey solution.
That said, I'm not sure how to actually load a new build of the application when it's available. The above can detect this - the generated SW registration file with my changes looks like this:
import debug from 'debug';
import { register } from 'register-service-worker';
if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
ready(...args) {
log('App is being served from cache by a service worker.\n', ...args);
},
cached(...args) {
log('Content has been cached for offline use.', ...args);
},
updated(...args) {
log('New content is available; please refresh.', ...args);
},
offline(...args) {
log('No internet connection found. App is running in offline mode.', ...args);
},
error(error, ...args) {
log('Error during service worker registration:', error, ...args);
}
});
}
When I make a new build of the application, and I refresh the app in a browser, the updated() callback is executed, but nothing else is done. When I tried adding:
window.location.reload(true);
which should be a forced refresh, I just get a refresh loop. I'm assuming this is because the service worker cache is completely independent from the browser cache and unaffected by things like the above or Ctrl+F5. (Which makes the "please refresh" rather misleading.)
Since this is going to mimic a native app, and it's supposed to be a simple line-of-business tool, I don't really need to do anything more complicated than immediately reload to the new version of the app when an update is available. How can I achieve this?
Okay so the behaviour I've observed is that the update does happen automatically, it's just not obvious as to what the exact sequence of events is. I'll try to describe my best understanding of how the generated service worker works in the installed PWA scenario. I'll speak in terms of "app versions" for simplicity, because the mental model behind this is closer to how apps, not webpages work:
You deploy v1 of your application to a server, install / precache it on a device, and run it for the first time.
When you suspend and resume your app, it does not hit your servers at all.
The app will check for an update when it's either cold-started, or you reload the page, i.e. using the pull down gesture on Android.
(Possibly also periodically as the cached version goes stale, but I haven't checked this.)
Say you've deployed v2 of your app in the meantime. Reloading an instance of v1 of the app will find this update, and precache it.
(One reason why prompting the user to reload doesn't seem to make sense. Whatever the reloading is meant to accomplish has already happened.)
Reloading an instance of v1 again does absolutely nothing. The app remains running between reloads, and you'll just get v1 afterwards.
(Reason number two why prompting the user to reload is pointless - it's not what causes a new version of an app to load.)
However, next time you cold start your app - e.g. nuke it from the task switcher and reopen - v2 of your app will be loaded and I'm guessing v1 will get cleaned out. That is, your app must fully shut down so an update will load.
In short, for an application to be updated from v1 to v2, the following steps need to occur:
Deploy v2 to server
Refresh instance of v1 on device, or shut down and reopen the app.
Shut down and reopen the app (again).

Xamarin.Mac: Launch another application with arguments in the sandbox

I implemented launch at login for my application using this tutorial:
https://blog.timschroeder.net/2012/07/03/the-launch-at-login-sandbox-project/
Basically you would need to implement a Helper app that will be registered to start at login and the Helper will launch your application.
The problem is that I would like to launch my application hidden and for that I need to pass it one argument. Unfortunately I didn't find any way to do that.
I found these methods to launch an App:
//Works to launch the app but no way to pass arg
var app = SBApplication.FromBundleIdentifier(PackageId);
app?.Activate();
//Same issue here
NSWorkspace.SharedWorkspace.OpenFile("/Applications/HelloWorld.app")
//If you run the code bellow outside of the sandbox it works fine.
//Inside of the sandbox it just launches the app but without args
var aTask = NSTask.LaunchFromPath("/usr/bin/open",
new string[] { "-a","HelloWorld.app", "--args", "--hidden" });
aTask.Launch();

Session time out on Liferay with multiple spring MVC portlet

Our application has been developed on Liferay with multiple Spring MVC portlets on the page. Its a single page application, and the navigation only happens inside the portlets. Now sometimes when Liferay session times out and I send a request to the control for a new view, the liferay login page is being shown inside the portlet. But the expected behaviour is if the liferay session is timed out, then the whole page should have redirected to Login page.
I have specified following properties in the portal-ext.properties
session.timeout.warning=1
session.timeout.auto.extend=false
session.timeout.redirect.on.expire=true
browser.cache.signed.in.disabled=true
Any suggestions?
If you're just doing Ajax navigation in the portlets, you might want to hook into Liferay's session-extension way (you'd have to look it up - there's a client side timer that counts down and displays the "session.timeout.warning" - I can't give pointers right now)
Alternatively, if a session extension is acceptable as long as a browser window is open, you can use the same mechanism to show an alternative behaviour: Instead of willingly timing out a session, it can extend the session. See portal(-ext).properties:
#
# Set the auto-extend mode to true to avoid having to ask the user whether
# to extend the session or not. Instead it will be automatically extended.
# The purpose of this mode is to keep the session open as long as the user
# browser is open and with a portal page loaded. It is recommended to use
# this setting along with a smaller "session.timeout", such as 5 minutes for
# better performance.
#
session.timeout.auto.extend=true
Does this happen in all your pages or only on specific pages. ?
Does this happen on click of any button?
If so , do the following in the method that you are calling on the click of the button,
function onClickFunction(){
var liferaySession = Liferay.Session._currentTime;
if(liferaySession == '0'){
//reload page
}
else{
//proceed
}
}

Delayed Job passenger production undefined method error

I am using delayed job version 2.1.4 with action mailer 3.0.8 to send my emails in background.
UserMailer.delay.newsletter(email)
It works with me fine in development and production Rails console.
But when it is called from my live production passenger server, it creates DJ but when this DJ runs, it throws
{undefined method `newsletter' for #<Class:0xc08afa0>
I think the problem
Any help?
The problem is with rails/passenger in production mode with class methods
So, I made a work around solution... I will try to call instance method and avoid to call class method.
Lets see an example; assuming I need to call the following method in background..
UserMailer.deliver_newsletter(email)
Then, I created a new class DelayClassMethod
class DelayClassMethod
def initialize(receiver_name, method_name, options={})
#receiver_name = receiver_name
#method_name = method_name
#parameters = options[:params] || []
end
def perform
eval(#receiver_name).send(#method_name, *#parameters)
end
end
and can run the method in background now by
DelayClassMethod.new("UserMailer", "deliver_newsletter", :params=>[email]).delay
So, I am running an instance method now in background which will run the class method.
Another example..
Assume I want to run
Product.list_all_by_user_and_category(user, category).delay
Then it can be run by
DelayClassMethod.new("Product", "list_all_by_user_and_category", :params => [user, category]).delay
My hunch is that you have multiple versions of the delayed_job in production. Are you using bundler to start your delayed job process?
I would recommend when doing bundle install in production, I would use the --binstubs flag to generate a wrapper around the delayed_job and use that executable to start the jobs.

Scoping sessions to a particular section of a Coldfusion application?

Is there a way to enable sessions for just a specific part of the Coldfusion application by just adding Application.cfm into its directory with the session enablers?
For example, a website that has the following:
/extranet
/intranet
/store
/rentals
I want to use session variables in the rental section, independent of the ones in the intranet and store.
If you don't want to share session variables, and don't need to share application variables, then it's easy. Just put a different Application.cfc (or .cfm) in the root of the context for which you want access to the session variables.
So if you want sessions in /extranet, and sessions in /intranet and don't want them to be the same application, then:
/extranet/Application.cfc:
component {
this.name = "extranet";
this.sessionmanagement = true;
}
/intranet/Application.cfc:
component {
this.name = "intranet";
this.sessionmanagement = true;
}
It sounds like you aren't really up to speed on all of the things that you can do with Application.cfc, so I'll also add that this is a really good reference. There is a lot to learn, but it is also pretty simple once you understand how it works.
Maybe a Single Signon (SSO) solution would work for you? Rather than monkey around with the values in the session struct, just pass a user id from one app to another. When the user passes from extranet to rentals, the app says "here comes user #45", the rentals app looks them up in the db, does some validation to make sure that the user is who the extranet says they are, then starts a new session for them in rentals.

Resources