the cmi.total_time parameter does not return anything - moodle

I am programming a SCORM 2004 product.
I can update the session_time, it works.
I can set the status (passed, failed, etc...)
I also can get the cmi.location time. No problems !
But I don't succeed to get the total time ! (cmi.total_time).
I have tested on 2 LMS :
On Ganesha the API.GetValue('cmi.total_time') is an empty string.
On Moodle the API.GetValue('cmi.total_time') is just a "P".
However i do have the correct logs with correct session times.
Anybody have an idea ?
Thank you !
EDIT.
I also try on cloud.scorm.com and cmi.total_time returns each time PT0H0M0S.
EDIT2. Ooops I deleted Donal's edit.

Based upon the information you've provided, I'm guessing that you're trying to set cmi.session_time and get cmi.total_time in the same learner session, which wouldn't give the response you're expecting.
cmi.total_time contains the total duration of all learner sessions prior to the current one, meaning that it won't contain the value you'd expect it to have until the second learner session.
Once you've set cmi.session_time, close the current learner session by leaving the SCO you're on, and then coming back to it. You should then see that cmi.total_time is now populated with a valid value.
Good Luck!

When you resume the second session and try to retrieve total time, are you able to retrieve the value you stored for cmi.location in the first session? If not, then you are probably not suspending the session. In order for data to be available in the next launch, you need to set cmi.exit to suspend before terminating the first session.
Mike

Related

Trouble with agent state chart

I'm trying to create an agent statechart where a transition should happen every day at 4 pm (except weekends).
I have already tried:
1. a conditional transition (condition: getHourOfDay() == 16)
2: A timeout transition that will "reinsert" my agent into the chart every 1 s and check if time = 16.
My code is still not running, does anyone have any idea how to solve it?
This is my statechart view. Customer is a single resource that is supposed to "get" the products out of my stock everyday at 4pm. It is supposed to happen in the "Active" state.
I have set a timeout transition (from Active-Active) that runs every 1s.
Inside my "Active" state in the "entrance action" i wrote my code to check if it is 4 pm and run my action if so.
I thought since i set a timeout transition it would check my condition every 1s, but apparently it is not working.
Your agent does not enter the Active state via an internal transition.
Redraw the transition to actually go out of the Active state and then enter it again as below:
Don't use condition-based transitions, for performance reasons. In your case, it also never triggers because it is only evaluated when something happens in the model. Incidentally, that is not the case at 4pm.
re your timeout approach: Why would you "reinsert" your agent into its own statechart? Not sure I understand...
Why not set up a schedule or event with your recurrence requirement and make it send a message to the statechart: stateChart.fireEvent("trigger!");. In your statechart, add a message-based transition that waits for this message. This will work.
Be careful to understand the difference between the Statechart.fireEvent() and the Statechart.receiveMessage() functions, though.
PS: and agree with Felipe: please start using SOF the way it is meant, i.e. also mark replies as solved. It helps us but also future users to quickly find solutions :-) cheers

Moving from file-based tracing session to real time session

I need to log trace events during boot so I configure an AutoLogger with all the required providers. But when my service/process starts I want to switch to real-time mode so that the file doesn't explode.
I'm using TraceEvent and I can't figure out how to do this move correctly and atomically.
The first thing I tried:
const int timeToWait = 5000;
using (var tes = new TraceEventSession("TEMPSESSIONNAME", #"c:\temp\TEMPSESSIONNAME.etl") { StopOnDispose = false })
{
tes.EnableProvider(ProviderExtensions.ProviderName<MicrosoftWindowsKernelProcess>());
Thread.Sleep(timeToWait);
}
using (var tes = new TraceEventSession("TEMPSESSIONNAME", TraceEventSessionOptions.Attach))
{
Thread.Sleep(timeToWait);
tes.SetFileName(null);
Thread.Sleep(timeToWait);
Console.WriteLine("Done");
}
Here I wanted to make that I can transfer the session to real-time mode. But instead, the file I got contained events from a 15s period instead of just 10s.
The same happens if I use new TraceEventSession("TEMPSESSIONNAME", #"c:\temp\TEMPSESSIONNAME.etl", TraceEventSessionOptions.Create) instead.
It seems that the following will cause the file to stop being written to:
using (var tes = new TraceEventSession("TEMPSESSIONNAME"))
{
tes.EnableProvider(ProviderExtensions.ProviderName<MicrosoftWindowsKernelProcess>());
Thread.Sleep(timeToWait);
}
But here I must reenable all the providers and according to the documentation "if the session already existed it is closed and reopened (thus orphans are cleaned up on next use)". I don't understand the last part about orphans. Obviously some events might occur in the time between closing, opening and subscribing on the events. Does this mean I will lose these events or will I get the later?
I also found the following in the documentation of the library:
In real time mode, events are buffered and there is at least a second or so delay (typically 3 sec) between the firing of the event and the reception by the session (to allow events to be delivered in efficient clumps of many events)
Does this make the above code alright (well, unless the improbable happens and for some reason my thread is delayed for more than a second between creating the real-time session and starting processing the events)?
I could close the session and create a new different one but then I think I'd miss some events. Or I could open a new session and then close the file-based one but then I might get duplicate events.
I couldn't find online any examples of moving from a file-based trace to a real-time trace.
I managed to contact the author of TraceEvent and this is the answer I got:
Re the exception of the 'auto-closing and restarting' feature, it is really questions about the OS (TraceEvent simply calls the underlying OS API). Just FYI, the deal about orphans is that it is EASY for your process to exit but leave a session going. This MAY be what you want, but often it is not, and so to make the common case 'just work' if you do Create (which is the default), it will close a session if it already existed (since you asked for a new one).
Experimentation of course is the touchstone of 'truth' but I would frankly expecting unusual combinations to just work is generally NOT true.
My recommendation is to keep it simple. You need to open a new session and close the original one. Yes, you will end up with duplicates, but you CAN filter them out (after all they are IDENTICAL timestamps).
The other possibility is use SetFileName in its intended way (from one file to another). This certainly solves your problem of file size growth, and often is a good way to deal with other scenarios (after all you can start up you processing and start deleting files even as new files are being generated).

In Hartl's tutorial, Listing 8.49, why is there a "forget(user)" option?

This is in relation to the checkbox that allows users to stay logged in when they close their browser. In an intermediate version, we remembered the user regardless, and now we're checking the params to see if the checkbox was set. This is the line of code that confuses me:
params[:session][:remember_me] == '1' ? remember(user) : forget(user)
Specifically, why are we forgetting the user if params[:session][:remember_me] is 0? Since we have never remembered the user (I think -- I'm a major newbie), wouldn't this work:
remember(user) if (params[:session][:remember_me] == '1')
and make more sense? I tried it and it passes the tests (which are very basic), but it also seems to behave appropriately. But maybe there's some stray variable that's staying set that I'm missing because I don't know what I'm doing.
I am at the exact same point and was wondering about the exact same thing.
And I came to the conclusion: it's only about security.
Because if an user never logs out of your app, an attacker who stole her user_id and remember_token cookies could use them all the time. However if the user eventually logs in on another computer either the remember_digest attribute gets a new value or is set to nil. Either way the attacker gets locked out.
By omitting forget(user) the only time the remember_digest is set to nil is when the user deliberately logs out.
However the version remember(user) if (params[:session][:remember_me] == '1') gives the user the ability to select one "remembered" computer.

Quickfix reset sequence number at start time but not set ResetSeqNum in Logon message

When the quickfix initiator reconnects at startTime (defined in config) it deletes the files with sequence number, but does not set ResetSeqNumFlag to Y, and the server replies with a Logout message with text "seq msg number to low ..."
Is there a way to set ResetSeqNumFlag = Y only for this behavior? I don`t want to reset the sequence on every log-on.
This appears to be a QuickFIX/J quirk (some might consider it a bug). If ResetOnLogon=N then no ResetSeqNumFlag=Y is sent when the session start time triggers a logon. If ResetOnLogon=Y, the ResetSeqNumFlag=Y is sent on every logon. I believe this is not a big problem in practice because participants in a FIX session typically reset their sequence numbers locally after a session ends (logically ends at the end time, not a connection disconnect).
If you want to slightly modify the source code to implement this behavior, you'd modify the quickfix.Session next() method. You could add a local flag that indicates a session has restarted (per the schedule as determined by checkSessionTime()). Pass that flag to generateLogon() and that method would use it to determine when to send ResetSeqNumFlag=Y regardless of the ResetOnLogon configuration.
I don`t want to reset the sequence on every log-on.
Then don't do it! Set ResetOnLogon=N.
At StartTime, the session will reset sequence numbers always. If ResetOnLogon=N, then they won't reset again until the next StartTime.
The initiator and acceptor should always have matching ResetOnXXX settings.
What you are asking cannot, should not be done. You start you engine with some config and then you change the config while running. If something goes wrong it will be very difficult to pinpoint what started the issue.
Instead of doing ResetSeqNumFlag = Y try adding ResetOnLogon=Y in your config for the acceptor side(that is if you have control over it) or ResetOnLogout=Y / ResetOnDisconnect=Y in your initiator config file. That would be much easier and changing config while running, is possibly not the best solution.
Your logout(disconnect can happen anytime) will happen anyways at EndTime anyways and should be easier for your application.

NSStream Event Timer - iPhone

All,
Is there a way to have a minimum time to keep a stream open before it closes? For some reason, my stream is closing prematurely which is causing errors elsewhere. I need to keep it open to make sure ALL of the data is gathered, and then it can run the other code.
Thanks,
James
In the case that someone falls upon this question later, I ended up creating nested if statements to pull it off.
Basically, there is one statement that checks if the end tag is not found (for my code, the END of the ENTIRE data that I should be receiving is </SessionData> - So, I did if([outputString rangeOfString:#"</SessionData>"].location == NSNotFound). I created a string called totalOutput that would have the outputString added onto the end of totalOutput until the </SessionData> is found.
If anyone ever needs help, just go ahead and comment on here and I can give more information.