Citrix
view release on metacpan or search on metacpan
Citrix/SessionSet.pm view on Meta::CPAN
our $ctxcols = "iSupd"; # t
# Arributes to use in the session collection (mapping to tab output format
# specifiers above). Notice col format specifiers in $ctxcols and this should match.
my @ctxattr = ('HOST_SID','STATE','USERNAME','APPID','DEVICE',); #'TYPE'
# OLD Unused: Legacy Default Citrix Query Timeout
#our $tout = 5;
# Provide a better alias (to use in API)
*Citrix::SessionSet::usersessions = \&Citrix::SessionSet::mysess;
=head1 METHODS
=head2 my $ss = Citrix::SessionSet->new($farmctx);
Construct a new Citrix session collection.
Indicate Farm context of query by $fc (See L<Citrix::Farm>).
Return empty session set (to be queried later)
=cut
sub new {
my ($class, $fc) = @_;
#OLD:my $ss = [];
if (!%$fc) {print("Session::new() : NO FC");return(undef);}
my $ss = {'sarr' => [], 'fc' => $fc};
bless($ss, $class);
return($ss);
}
=head2 $err = $ss->gethostsess('the-cx-host-67');
Get all sessions for a single host (passed as $host) and load the sessions (adding them) into
session set instance.
Return 1 for errors, 0 on success.
=cut
sub gethostsess {
my ($ss, $host) = @_;
my $sarr = $ss->getsessions();
my $fh;
my $ap = '';
my $fc = $ss->farmctx();
my $mh = $ss->getmh(); # $fc->masterhost();
my $ds = $fc->domainsuffix(); # OLD: {'ds'}
my $cnt = scalar(@$sarr);
my $usehost; # Final Host to use for query
my $tout = $Citrix::touts->{'host'}; # 10;
my @times = ();
my $trace = debug($ss);
if ($trace && $ENV{'HTTP_HOST'}) {print("<pre>");}
#if ($host =~ /\./) {die("Expecting bare hostname (got: $host)");}
if (!$host) {$usehost = $mh;$ap = ' -S';}
elsif ($ds) {$usehost = "$host.$ds";}
my $cmd = "rsh $usehost $Citrix::binpath/ctxquery -f $ctxcols $ap"; # -S
# Added loading of Net::Ping to circumvent
eval {require(Net::Ping);};
if ($@) {} # print("Dont have Net::Ping (risk hanging)");
else {
my $p = Net::Ping->new();
if ($p->ping($usehost)) {if ($trace) {print("$usehost is alive (reachable by PING).\n");}}
# Reuse $tout as state variable
else {$tout = 0;}
$p->close();
if (!$tout) {$ss->{'msg'} = "$usehost NOT Alive.\n";return(1);}
}
if ($trace) {print("Launch Query: $cmd\n");$times[0] = time();}
eval {
local $SIG{'ALRM'} = sub {
die("RSH Timeout ($usehost)\n");
die("Host '$usehost' was unable to return session within $tout\n");
};
#local $SIG{'CHLD'} = sub {die("Child ($usehost)\n");};
alarm($tout);
if ($trace) {print("Opening Pipe ...\n");}
my $ok = open($fh, "$cmd |");
if (!$ok) {die("Failed to open the pipe");}
if ($trace) {print("Opened: '$cmd' (as $< / $>)\n");}
};
# Enforce reset in a place which is always visited
alarm(0);
if ($trace) {$times[1] = time();print("Done Trying (Success, ",($times[1]-$times[0])," s.)\n");}
if ($trace) {print("Reset Timeout ($tout => 0)\n");}
if ($@) {$ss->{'msg'} = $@;return(2);}
if ($trace) {print("Parse Query (From: $fh)\n");}
parse($fh, $sarr, \@ctxattr);
my $cnt2 = scalar(@$sarr);
if ($host) {
my $cd = ($cnt2 - $cnt);
$ss->{'stat'}->{$host}->{'cnt'} = $cd;
#if (!$cd) {$ss->{'stat'}->{$host}->{'out'} = "$!";}
}
if ($trace && $ENV{'HTTP_HOST'}) {print("</pre>\n");}
return(0);
}
=head2 $err = $ss->getsession('the-cx-host-67:5234');
Get a session identified by $hostsess string (HOST:SESSID) from session set
(Involves sequential search within session set as sessions are not
indexed in current version).
The composite key of form "HOST:SESSID" is required, because session set may contain
sessions from multiple hosts (With single farm context though).
Return the single identified session (as hash) or undef if no session by SESSID
is found.
=cut
sub getsession {
my ($ss, $hostsess) = @_;
my $sarr = $ss->getsessions();
my (@s) = grep({$_->{'HOST_SID'} eq $hostsess} @$sarr);
if (@s < 1) {$ss->errstr("No Sessions for $hostsess'' ");return(undef);}
if (@s > 1) {$ss->errstr("Multiple session for Identified session '$hostsess'");return(undef);}
#ORG:return((@s == 1) ? $s[0] : undef);
return($s[0]);
}
=head2 $err = $ss->mysess('joecitrix');
( run in 1.762 second using v1.01-cache-2.11-cpan-39bf76dae61 )