# HG changeset patch # User "Rex Tsai " # Date 1226852804 -28800 # Node ID a654d43731f0faedcc4c6f0789a6a410e9425437 # Parent c30080146c050d46b1628de6ab8ade15790683d9 implement multi-thread Ikariam::Scanner diff -r c30080146c05 -r a654d43731f0 Ikariam.pm --- a/Ikariam.pm Mon Nov 17 00:25:56 2008 +0800 +++ b/Ikariam.pm Mon Nov 17 00:26:44 2008 +0800 @@ -118,16 +118,23 @@ debug => undef, }; - # if debug LWP::Debug::level('+trace'); - $self->{mech}->cookie_jar(HTTP::Cookies->new(file => "/tmp/ikariam-cookies.txt", autosave => 1)); + $self->{mech}->cookie_jar(HTTP::Cookies->new(file => "/tmp/ikariam-$server-cookies.txt", autosave => 1, ignore_discard => 1)); $self->{mech}->default_headers->push_header('Accept-Encoding', 'deflate'); return bless $self, $class; } +sub clone +{ + my $self = shift; + my $copy = bless { %$self }, ref $self; # copy most fields + + $copy; +} + sub viewAlly { my $self = shift; diff -r c30080146c05 -r a654d43731f0 scan.pl --- a/scan.pl Mon Nov 17 00:25:56 2008 +0800 +++ b/scan.pl Mon Nov 17 00:26:44 2008 +0800 @@ -3,12 +3,30 @@ use Data::Dumper; use Carp; use Ikariam; +use Parallel::ForkManager; package main; +package Ikariam::Scanner; +use strict; +use Carp; +use Ikariam; +use Data::Dumper; +use Parallel::ForkManager; + +sub new { + my($class, $i) = @_; + warn("new scanner"); + my $self = { + ikariam => $i, + }; + + return bless $self, $class; +} + sub saveCities { - my ($island, @cities) = @_; + my ($self, $island, @cities) = @_; if ($#cities == -1) { warn ("empty cities list.\n"); @@ -16,7 +34,8 @@ } foreach my $h_city (@cities) { -# Carp::carp(sprintf("checking %s\n", $h_city->{'cityname'})); + # Carp::carp(sprintf("checking %s\n", $h_city->{'cityname'})); + print(STDERR sprintf("checking cityname %s\n", $h_city->{'cityname'})); $h_city->{island} = $island; $h_city->{'time'} = time; my $c = Ikariam::Cities->retrieve($h_city->{cityId}); @@ -32,43 +51,47 @@ my $user = Ikariam::User->retrieve($h_city->{'user'}); next if (defined($user) && defined($user->time) && $user->time gt (time - 30*60)); - saveUser($h_city->{owner}); + $self->saveUser($h_city->{owner}); } } sub saveUser { + my $self = shift; my $userName = shift; my $users; foreach my $x (qw/score army_score_main trader_score_secondary/) { - $users = $::i->viewScore($x, $userName, 0); + my $i = $self->{ikariam}->clone(); + $users = $i->viewScore($x, $userName, 0); foreach my $h_user (values(%{$users})) { -# Carp::carp(sprintf("Saving user %s\n", $h_user->{'name'})); + # Carp::carp(sprintf("Saving user %s\n", $h_user->{'name'})); $h_user->{'time'} = time; - my $user = Ikariam::User->retrieve($h_user->{'id'}); if(defined($user)) { + # check if the arm score is down foreach (keys(%$h_user)) { $user->set($_ => $h_user->{$_}); } } else { $user = Ikariam::User->insert($h_user); } $user->update(); - saveAlly($h_user->{allyId}); + $self->saveAlly($h_user->{allyId}); } } } sub saveAlly { + my $self = shift; my $allyId = shift; return unless (defined($allyId) && $allyId ne '0'); # Save for member of ally my $ally = Ikariam::Ally->retrieve($allyId); if(!defined($ally) || $ally->time le (time - 30*60*1)) { - my $h_ally = $::i->viewAlly($allyId); + my $i = $self->{ikariam}->clone(); + my $h_ally = $i->viewAlly($allyId); $h_ally->{'time'} = time; if(defined($ally)) { foreach (keys(%$h_ally)) { $ally->set($_ => $h_ally->{$_}); } @@ -79,12 +102,15 @@ } sub saveIslands { - my @islands = @_; + my ($self, @islands) = @_; + + my $pm = new Parallel::ForkManager(10); foreach my $h_island (@islands) { - # printf("checking island %d\n", $h_island->{id}); - + my $pid = $pm->start and next; + + printf("checking island %d\n", $h_island->{id}); my $island; if($island = Ikariam::Island->retrieve($h_island->{id})) { foreach my $i (keys(%$h_island)) { @@ -98,16 +124,22 @@ # 10 minutes cache. if($island->time le (time - 60*10)) { - my @cities = $::i->viewIsland($h_island->{id}); - saveCities($h_island->{id}, @cities); + my $i = $self->{ikariam}->clone(); + my @cities = + $i->viewIsland($h_island->{id}); + $self->saveCities($h_island->{id}, @cities); $island->set('time', time); } $island->update(); - + $pm->finish; } + $pm->wait_all_children; } +1; + +package main; # local $SIG{ALRM} = sub { die "timeout\n" }; # alarm 3; @@ -116,24 +148,23 @@ if($#ARGV == 1) { $i->login; my @islands = $i->viewWorldMap($ARGV[0], $ARGV[1]); - saveIslands(@islands); - $i->logout; + # my $s = new Ikariam::Scanner($i); + # $s->saveIslands(@islands); + new Ikariam::Scanner($i)->saveIslands(@islands); } elsif($#ARGV == 0) { $i->login; my $island = $ARGV[0]; my @cities = $i->viewIsland($island); - saveCities($island, @cities); - $i->logout; + new Ikariam::Scanner($i)->saveCities($island, @cities); } elsif($#ARGV == -1) { $i->login; my $cities = $i->check; # random foreach my $cityId (keys(%$cities)) { -# Carp::carp(sprintf("Checking island location [%s:%s]\n", $cities->{$cityId}->{island}->{x}, $cities->{$cityId}->{island}->{y})); my @islands = $i->viewWorldMap( $cities->{$cityId}->{island}->{x}, $cities->{$cityId}->{island}->{y}); - saveIslands(@islands); + new Ikariam::Scanner($i)->saveIslands(@islands); } - $i->logout; } else { die("Usage: $0\nUsage: $0 x y\n"); } +$i->logout;