The session loads fine for the most part but it is randomly clearing all of the data some times and I don't know why:
Create my new session:
$session = CGI::Session->new( "driver:file",undef,{Directory => '/tmp'} );
$session->param('logged_in', 1);
$session->expire('logged_in', '+10m');
$session->expire('+1h');
Now when I go to another page and load the session I do:
$session = CGI::Session->load ( "driver:file", $sid, {Directory => '/tmp'} );
return 0 if $session->is_expired;
return 0 if !$session->param('logged_in');
return $session;
The problem I have is that sometimes, before the 10 minute mark is up the 'logged_in' param is empty when it should not be. Why could this be happening?
First, you do not seem to be using strict: You should. Second, don't use indirect object notation. I.e., use CGI::Session->new.
To find out what is going on, use the sequential id generator for debugging and make sure you are looking at the session you think you are looking at. Make sure you create the session on log on, but from that point on, you load it.
Check how you are keeping track of the session id: Are you using cookies, query string parameters or from parameters? Make sure the correct session id is available at all times.
Related
My QuickFIX initiator may manage 5 sessions (targets). I can use ReconnectInterval to control the reconnect-try frequency.
Assume one session connection gives me a problem but I don't want to stop the other 4 connections. I also don't want the problematic session to keep on trying to connect.
Is there any way to stop and later to restart this particular session connection?
Quickfix does not provide an intuitive way to disable a session.
void Initiator::connect()
{
Locker l(m_mutex);
SessionIDs disconnected = m_disconnected;
SessionIDs::iterator i = disconnected.begin();
for ( ; i != disconnected.end(); ++i )
{
Session* pSession = Session::lookupSession( *i );
if ( pSession->isEnabled() && pSession->isSessionTime(UtcTimeStamp()) )
doConnect( *i, m_settings.get( *i ));
}
}
The code above is the loop that keeps trying to maintain all the sessions connected. Looking up to the code, there are two ways to avoid the connection of a session: 1. Disabling the session; 2. Limiting the session time range (there is no way to do it after session initialization, so it's not a valid option).
The method pSession->isEnabled basically returns Session.m_state.m_enabled, but there is no way to access the SessionState object properties, once m_state is private. The only way to set m_enabled to false and avoid the connection tries is by calling Session.logout():
FIX::SessionID session_id("FIX.4.2", "CLIENT1", "EXECUTOR");
FIX::Session* mysession = initiator->getSession(session_id);
mysession->logout();
In my server program I need to have ability to iterate every 5 minutes through all opened connections and see which is really "active" or not.
I know that the best approach is to use "heart beat", but then, the server need to have somehow ability to check weather the connection is "off" in order to delete the associated "user parameters" that is attached to the connection.
My first approach was to use "Async" module, but this works in a separate process - so I cannot delete any element from the main process unless I use a technique to invoke a subroutine from the main process called from the child process (I don't know how, any help will be warmly welcomed).
Another possibility using Async is create a static client that is all the time on (also in the server) and sending "commands" to the server, but to me it looks "too exaggerating" to create such "wasting memory" client in the server, and also "eat" CPU time (I think much more than simple event like equivalent to "setTimeout" in JS).
Yet another approach is to use EV: But when I call EV::run it will NOT RUN anything ELSE than this "periodic event" - means that it will not reach the next line where the ->Start for the server is.
Placing it after the ->Start will make this event useless too: As the server works the program will not go behind the ->Start line.
Using EV::run EV::RUN_NOWAIT; will make the server work, but the EV will somehow not work, for a strange reason (Anyone know how can I still make it work?)
I prefer to not use Net::Websocket::EV, because as per their script, it doesn't do the handshake automatically, and many things (as well as SSL connection that I have) I will need to do manually and for me it is change a lot in my program.
PROBLEM SUMMARY:
How to make the code in EV run every 5 minutes, together with the server?
my %CON; # Connections (And user data) hash
my $__ConChk=EV::periodic 0, 300, 0, sub {
my #l=keys %CON;
for(my $i=0 ; $i<#l ; $i++) {
if($CON{$l[$i]}{"T"}+3600<time()) { # I give one hour time to be completely offline (for different reasons)
$CON{$l[$i]}{"C"}->disconnect(); delete $CON{$l[$i]};
}
}
};
EV::run EV::RUN_NOWAIT; # This is not working - Seems to be ignored!
Net::WebSocket::Server->new(
listen => $ssl, # Earlier preset
silence_max=>60, # Time to just shut the connection off, but don't delete user data
on_connect => sub {
my($serv,$conn)=#_;
my $cid; # Connection ID (for the hash)
$conn->on(
handshake => sub {
my($conn,$handshake)=#_;
# Create user data in $CON{$cid}
},
binary => sub {
$CON{$cid}{"T"}=time();
# Handling of single incomming message (command)
},
disconnect => sub {
# Do NOT DELETE THE ENTRY!! Maybe the connection drop due to instability!!
}
);
}
)->start; # This will run - but ignoring EV::run - what to do....?
undef $__ConChk;
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).
I have a form that is submitted from view, before processing the form I checked the role, if everything is alright then I will insert/edit/delete/approve the data depends on which submit button is pressed, like below:
def input_form = withAccess { username => implicit request =>
submitSOForm.bindFromRequest.fold (
hasErrors = { form =>
....
)},
success = { userData =>
if (Sales_Order.check(userData,"insert")) {
//using cache to pass the userData
Cache.set("userData", userData, 60)
if(request.body.asFormUrlEncoded.get("action")(0) == "Save" || request.body.asFormUrlEncoded.get("action")(0) == "Ask for Approval")
Redirect(routes.SalesOrders.insert(request.body.asFormUrlEncoded.get("action")(0)))
else
Redirect(routes.SalesOrders.approval("insert", request.body.asFormUrlEncoded.get("action")(0)))
}
else
Redirect(routes.SalesOrders.index).withSession(Security.username -> username, "timestamp" -> System.currentTimeMillis.toString).flashing(Flash() + ("invalid" -> "Inconsistent Input Data.") + ("insert" -> "block"))
}
)
}
Everything works fine, I can get the userData either in insert or approval action method. However, I'm not sure using cache is the right choice. I imagine if there is a lot of request to input_form, then it will remove arbitrary data from the cache which is explained in the documentary.
An important point about the cache is that it behaves just like a cache should:
the data you just stored may just go missing.
So, what I'm asking here is there any better way to passing that userData without using Cache ?
First thing is: you don't need to afraid cache's loose between requests - it's rather information that you shouldn't use it as a regular persistence layer.
For main question: most probably Flash scope will be more suitable solution for this task.
Remember that cache values will be available for other users, so if some user will perform similar action in the almost the same time (60 seconds) it will get value from others action - Flash as it's stored in the cookie will be individual.
If you want to stay with cache - (i.e. in case that you want to store objects much bigger than 4kb) at least make sure that the cache keys contains some user specific, unique elements, like:
Cache.set("userData"+currentUser.id, userData, 60)
I am trying to load a configuration file into a hash during my PerlChildInitHandler and then access the values from PerlResponseHandler. However, even though the process number is the same, it seems that variables changed during the child_init() call revert back to their default values when handler() gets called.
The basic scenario is:
package StartupLog;
# the variable I'm testing
my $sticky = 0;
sub child_init {
$sticky = 1;
return 0;
}
sub handler {
warn __PACKAGE__ . " sticky = $sticky\n"; ### always says "0" but should say "1"
return 0;
}
1;
This was never answered, so eventually I moved on to using the PerlPostConfigHandler, which seemed to work acceptably. I can only assume it's something about the forking that happens in the PerlChildInitiHandler but, sorry to say, I gave up. Hope this helps someone in the future.
Generally, if you want to load something at childinit time, and access it in the response phase, you'd stuff it into a package global (like $My::variable = 'lols'). I've never tried to do it the way you are here. Did you try using our instead of my maybe?.