question

shadoof avatar image
shadoof asked

Session Attributes

I noticed a little weirdness in the way that the ASK API handles sessions and session attributes (values stored in a session). I know that super-helpful jjaquinta says that we should use DynamoDB to handle persistence better, on the basis of UserIDs, but that would be a lot of set up, for my project anyway. Also, shouldn't the documentation tell us about this one? Anyway, does anyone know: if you are using Lambda and coding in Java, when do session attributes actually get updated? In my experience this seems to happen without being synchronized with the flow of control of my code, at, say, a later point than I would expect. Real world example: an intent updates a session attribute and then immediately prompts - giving an askResponse - for another intent. The new intent fetches the session attribute but it has not changed? or it has not change ... yet? Is there any way around this (other than DynamoDB)? (I guess this is not really 'getting started' but on the other hand it's something that should be in the documentation, even what is ... so far ... out there.)
alexa skills kitdebugging
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

jjaquinta avatar image
jjaquinta answered
First of all, thanks for saying I'm "super helpful". :-) Second of all, session attributes aren't magic. You, and only you, set them. Alexa does almost nothing with them. Whatever goes out, when you send the response from your agent, comes back, [i]if there is any reply from Alexa[/i]. If Alexa drops the line... poof... the session info is gone. Alexa does not persist these values. They exist as long as that blue light is blinking. I generally follow a very consistent structure in my Java code. I have a bean that I create to represent current state. My speechlet handler routes all invocations through a single point in my logic. The first thing done in my logic is to create and populate the state bean. If I'm using session attributes, I decipher them there, or give them default values, if absent. If I'm persisting in DynamoDB, I do the same. The rest of the logic proceeds, branches based on intent and state. Response text and card text are assembled in the state bean. Last thing is another function composes the reply blob, and the persists any info that needs to be retained into either session attributes or offline storage. My main entry point to Starlanes looks like this: [code] public static SpeechletResponse interact(SpeechletRequest request, Session session) { StarlanesState state = getFromSession(session); if (request instanceof SessionEndedRequest) return null; else if (request instanceof IntentRequest) handleIntent(state, (IntentRequest)request); else if (request instanceof LaunchRequest) handleLaunch(state, (LaunchRequest)request); else state.respond("I'm not sure what happened there."); if (state.getResponse().indexOf("[[title=") < 0) state.respond("[[title=Starlanes]]"); setToSession(state, session); return ResponseUtils.buildSpeechletResponse(state.getResponse().toString()); } [/code] Overall, I've mostly given up on Lambda. It is too restrictive. All my serious skills just use Lambda to pass through to a web servlet. That gives you additional options. Instead of persisting in Dynamo, you can persist in memory. I use a Map with the user ID as a key. That's great if you want to keep some info around, but not necessarily forever. In other skills, I occasionally write this memory map to disk, and read it in on startup. That's kind of a halfway house between Dynamo and semi-persistent. Since Lambda dumps your JVM between calls, you can't do the in-memory thing.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

shadoof avatar image
shadoof answered
Thanks. This was also super-helpful ;) The 'weirdness' mentioned in my previous post was - chiefly - of my own making. I know have ASK sessions working as I would expect through Java and Lambda. I will graduate to less restrictive and better persistence in one of the good ways you mention in the future.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

cdburns123 avatar image
cdburns123 answered
Another way I do it on my own box is to set environment variables for specific things that I don't want changed or lost, even on a reboot. Of course, you could also read/write it out to a comma delimited text file and load it up into an array when you start your program or when changes occur. Many options if you have it come back to your own server in regards to db.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Galactoise avatar image
Galactoise answered
I have a a kind of interesting anecdote about session attributes vs. heavier session management. A group of three of my coworkers and I were using an Echo as part of a hack week project, and we were pretty heavily using session attributes for disambiguation of where we were in the conversation flow. We had been having a back-and-forth argument about session attributes vs. in memory session management, but were still with the simpler attributes implementation at that point. While we were testing with the echo on our single shared test server, one of us decided it would be a good time to upload some new code and bounce the service. Because we were using attributes and everything was completely stateless, the service actually restarted in time to get the reply from the user and carried on as if nothing had happened. Suffice it to say, that was enough to win over the holdouts to the session attributes camp.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.