Changeset a957e9285b443c0e7c978318a7e67324b6085139
- Timestamp:
- 10/18/09 15:59:29 (5 weeks ago)
- Author:
- Alex Vandiver <alexmv@mit.edu>
- git-author:
- Alex Vandiver <alexmv@mit.edu> / 2009-03-22T02:06:46Z-0400
- Parents:
- 99cc3dceec1bb97699f4e130556ce22975e39b6f
- Children:
- f3678c324b8086ca07cd0baaa425a0aa99a75524
- git-committer:
- Alex Vandiver <alexmv@mit.edu> / 2009-10-18T15:59:29Z-0400
- Message:
-
Make Jabber try to reconnect when disconnected, at exponential intervals
Make the ConnectionManager store auth information on connect, and use
that auth information to try to reconnect and re-auth. Use some
simple exponential backoff, capped at 5 minutes, as intervals for
reconnecting.
- Location:
- perl/modules/Jabber/lib/BarnOwl/Module
- Files:
-
Legend:
- Unmodified
- Added
- Removed
-
|
rf798d02
|
ra957e92
|
|
| 132 | 132 | |
| 133 | 133 | foreach my $jid ( $conn->getJIDs() ) { |
| | 134 | |
| | 135 | next unless $conn->jidActive($jid) or $conn->tryReconnect($jid); |
| | 136 | |
| 134 | 137 | my $client = $conn->getConnectionFromJID($jid); |
| 135 | | |
| 136 | 138 | unless($client) { |
| 137 | 139 | $conn->removeConnection($jid); |
| … |
… |
|
| 140 | 142 | my $status = $client->Process(0); # keep-alive |
| 141 | 143 | if ( !defined($status) ) { |
| 142 | | BarnOwl::error("Jabber account $jid disconnected!"); |
| 143 | | do_logout($jid); |
| 144 | | next; |
| | 144 | $conn->scheduleReconnect($jid); |
| 145 | 145 | } |
| 146 | 146 | if ($::shutdown) { |
| … |
… |
|
| 383 | 383 | } |
| 384 | 384 | |
| 385 | | if ( $conn->jidExists($jidStr) ) { |
| | 385 | if ( $conn->jidActive($jidStr) ) { |
| 386 | 386 | BarnOwl::error("Already logged in as $jidStr."); |
| 387 | 387 | return; |
| | 388 | } elsif ($conn->jidExists($jidStr)) { |
| | 389 | return $conn->tryReconnect($jidStr, 1); |
| 388 | 390 | } |
| 389 | 391 | |
| … |
… |
|
| 453 | 455 | BarnOwl::error( "Error in connect: " . join( " ", @result ) ); |
| 454 | 456 | } else { |
| | 457 | $conn->setAuth( |
| | 458 | $jidStr, |
| | 459 | { %{ $vars{jlogin_authhash} }, |
| | 460 | password => $vars{jlogin_password} |
| | 461 | } |
| | 462 | ); |
| 455 | 463 | my $roster = $conn->getRosterFromJID($jidStr); |
| 456 | 464 | $roster->fetch(); |
| … |
… |
|
| 463 | 471 | $client->{fileno} = $client->getSocket()->fileno(); |
| 464 | 472 | #queue_admin_msg("Connected to jabber as $fullJid ($client->{fileno})"); |
| 465 | | BarnOwl::add_dispatch($client->{fileno}, sub { $client->OwlProcess() }); |
| | 473 | BarnOwl::add_dispatch($client->{fileno}, sub { $client->OwlProcess($fullJid) }); |
| 466 | 474 | |
| 467 | 475 | # populate completion from roster. |
-
|
r5f3168a
|
ra957e92
|
|
| 142 | 142 | sub OwlProcess { |
| 143 | 143 | my $self = shift; |
| | 144 | my $jid = shift || $self->{SESSION}->{FULLJID}; |
| 144 | 145 | my $status = $self->Process(0); |
| 145 | 146 | if ( !defined($status) ) { |
| 146 | | my $jid = $self->{SESSION}->{FULLJID}; |
| 147 | | BarnOwl::error("Jabber account $jid disconnected!"); |
| 148 | | BarnOwl::Module::Jabber::do_logout($jid); |
| | 147 | $BarnOwl::Module::Jabber::conn->scheduleReconnect($jid); |
| 149 | 148 | } |
| | 149 | } |
| | 150 | |
| | 151 | =head2 Disconnect |
| | 152 | |
| | 153 | Work around a bug in Net::Jabber::Client where Process' return status |
| | 154 | is not cleared on disconnect. |
| | 155 | |
| | 156 | =cut |
| | 157 | |
| | 158 | sub Disconnect { |
| | 159 | my $self = shift; |
| | 160 | delete $self->{PROCESSERROR}; |
| | 161 | return $self->SUPER::Disconnect(@_); |
| 150 | 162 | } |
| 151 | 163 | |
-
|
r8ff511d
|
ra957e92
|
|
| 41 | 41 | if $self->{$jidStr}->{Client}; |
| 42 | 42 | delete $self->{$jidStr}; |
| | 43 | |
| | 44 | return 1; |
| | 45 | } |
| | 46 | |
| | 47 | sub scheduleReconnect { |
| | 48 | my $self = shift; |
| | 49 | my $jidStr = shift; |
| | 50 | return 0 unless exists $self->{$jidStr}; |
| | 51 | BarnOwl::admin_message(Jabber => "Disconnected from jabber account $jidStr"); |
| | 52 | |
| | 53 | BarnOwl::remove_dispatch($self->{$jidStr}->{Client}->{fileno}) if $self->{$jidStr}->{Client}->{fileno}; |
| | 54 | $self->{$jidStr}->{Client}->Disconnect() |
| | 55 | if $self->{$jidStr}->{Client}; |
| | 56 | |
| | 57 | $self->{$jidStr}->{Status} = "reconnecting"; |
| | 58 | $self->{$jidStr}->{ReconnectBackoff} = 5; |
| | 59 | $self->{$jidStr}->{ReconnectAt} = time + $self->{$jidStr}->{ReconnectBackoff}; |
| | 60 | return 1; |
| | 61 | } |
| | 62 | |
| | 63 | sub setAuth { |
| | 64 | my $self = shift; |
| | 65 | my $jidStr = shift; |
| | 66 | $self->{$jidStr}->{Auth} = shift; |
| | 67 | } |
| | 68 | |
| | 69 | sub tryReconnect { |
| | 70 | my $self = shift; |
| | 71 | my $jidStr = shift; |
| | 72 | my $force = shift; |
| | 73 | |
| | 74 | return 0 unless exists $self->{$jidStr}; |
| | 75 | return 0 unless $self->{$jidStr}{Status} eq "reconnecting"; |
| | 76 | return 0 unless $force or (time > $self->{$jidStr}{ReconnectAt}); |
| | 77 | |
| | 78 | $self->{$jidStr}->{ReconnectBackoff} *= 2; |
| | 79 | $self->{$jidStr}->{ReconnectBackoff} = 60*5 |
| | 80 | if $self->{$jidStr}->{ReconnectBackoff} > 60*5; |
| | 81 | $self->{$jidStr}->{ReconnectAt} = time + $self->{$jidStr}->{ReconnectBackoff}; |
| | 82 | |
| | 83 | my $status = $self->{$jidStr}->{Client}->Connect; |
| | 84 | return 0 unless $status; |
| | 85 | |
| | 86 | my @result = $self->{$jidStr}->{Client}->AuthSend( %{ $self->{$jidStr}->{Auth} } ); |
| | 87 | if ( !@result || $result[0] ne 'ok' ) { |
| | 88 | $self->removeConnection($jidStr); |
| | 89 | BarnOwl::error( "Error in jabber reconnect: " . join( " ", @result ) ); |
| | 90 | return 0; |
| | 91 | } |
| | 92 | |
| | 93 | BarnOwl::admin_message(Jabber => "Reconnected to jabber as $jidStr"); |
| | 94 | $self->{$jidStr}{Status} = "available"; |
| 43 | 95 | |
| 44 | 96 | return 1; |
| … |
… |
|
| 88 | 140 | } |
| 89 | 141 | |
| | 142 | sub jidActive { |
| | 143 | my $self = shift; |
| | 144 | my $jidStr = shift; |
| | 145 | return(exists $self->{$jidStr} and $self->{$jidStr}{Status} eq "available"); |
| | 146 | } |
| | 147 | |
| 90 | 148 | sub sidExists { |
| 91 | 149 | my $self = shift; |
| … |
… |
|
| 110 | 168 | my $jid = shift; |
| 111 | 169 | $jid = $jid->GetJID('full') if UNIVERSAL::isa($jid, 'Net::XMPP::JID'); |
| 112 | | return $self->{$jid}->{Client} if exists $self->{$jid}; |
| | 170 | return $self->{$jid}->{Client} if $self->jidActive($jid); |
| 113 | 171 | } |
| 114 | 172 | |
| … |
… |
|
| 127 | 185 | my $jid = shift; |
| 128 | 186 | $jid = $jid->GetJID('full') if UNIVERSAL::isa($jid, 'Net::XMPP::JID'); |
| 129 | | return $self->{$jid}->{Roster} if exists $self->{$jid}; |
| | 187 | return $self->{$jid}->{Roster} if $self->jidExists($jid); |
| 130 | 188 | } |
| 131 | 189 | |