Loading lib/Travelynx/Command/work.pm +32 −107 Original line number Diff line number Diff line Loading @@ -21,18 +21,14 @@ sub run { my $checkin_deadline = $now->clone->subtract( hours => 48 ); my $json = JSON->new; my $db = $self->app->pg->db; my $num_incomplete = $self->app->in_transit->delete_incomplete_checkins( earlier_than => $checkin_deadline ); my $res = $db->delete( 'in_transit', { checkin_time => { '<', $checkin_deadline } } ); if ( my $rows = $res->rows ) { $self->app->log->debug("Removed ${rows} incomplete checkins"); if ($num_incomplete) { $self->app->log->debug("Removed ${num_incomplete} incomplete checkins"); } for my $entry ( $db->select( 'in_transit_str', '*', { cancelled => 0 } )->hashes->each ) { for my $entry ( $self->app->in_transit->get_all_active ) { my $uid = $entry->{user_id}; my $dep = $entry->{dep_eva}; Loading Loading @@ -63,61 +59,26 @@ sub run { die("could not find train $train_id at $dep\n"); } # selecting on user_id and train_no avoids a race condition when # a user checks into a new train while we are fetching data for # their previous journey. In this case, the new train would # receive data from the previous journey. $db->update( 'in_transit', { dep_platform => $train->platform, real_departure => $train->departure, route => $json->encode( [ $self->app->iris->route_diff($train) ] ), messages => $json->encode( [ map { [ $_->[0]->epoch, $_->[1] ] } $train->messages ] ), }, { user_id => $uid, train_no => $train->train_no } $self->app->in_transit->update_departure( uid => $uid, train => $train, route => [ $self->app->iris->route_diff($train) ] ); if ( $train->departure_is_cancelled and $arr ) { my $checked_in = $self->app->in_transit->update_departure_cancelled( uid => $uid, train => $train, dep_eva => $dep, arr_eva => $arr, ); # depending on the amount of users in transit, some time may # have passed between fetching $entry from the database and # now. Ensure that the user is still checked into this train # before calling checkout to mark the cancellation. if ( $db->select( 'in_transit', 'count(*) as count', { user_id => $uid, train_no => $train->train_no, checkin_station_id => $dep, checkout_station_id => $arr, } )->hash->{count} ) { $db->update( 'in_transit', { cancelled => 1, }, { user_id => $uid, train_no => $train->train_no, checkin_station_id => $dep, checkout_station_id => $arr, } ); # now. Only check out if the user is still checked into this # train. if ($checked_in) { # check out (adds a cancelled journey and resets journey state # to checkin Loading Loading @@ -173,50 +134,15 @@ sub run { return; } # selecting on user_id, train_no and checkout_station_id avoids a # race condition when a user checks into a new train or changes # their destination station while we are fetching times based on no # longer valid database entries. $db->update( 'in_transit', { arr_platform => $train->platform, sched_arrival => $train->sched_arrival, real_arrival => $train->arrival, route => $json->encode( [ $self->app->iris->route_diff($train) ] ), messages => $json->encode( [ map { [ $_->[0]->epoch, $_->[1] ] } $train->messages ] ), }, { user_id => $uid, train_no => $train->train_no, checkout_station_id => $arr } my $checked_in = $self->app->in_transit->update_arrival( uid => $uid, train => $train, route => [ $self->app->iris->route_diff($train) ], arr_eva => $arr, ); if ( $train->arrival_is_cancelled ) { # depending on the amount of users in transit, some time may # have passed between fetching $entry from the database and # now. Ensure that the user is still checked into this train # before calling checkout to mark the cancellation. if ( $db->select( 'in_transit', 'count(*) as count', { user_id => $uid, train_no => $train->train_no, checkout_station_id => $arr } )->hash->{count} ) { if ( $checked_in and $train->arrival_is_cancelled ) { # check out (adds a cancelled journey and resets journey state # to destination selection) $self->app->checkout( Loading @@ -225,7 +151,6 @@ sub run { uid => $uid ); } } else { $self->app->add_route_timestamps( $uid, $train, 0 ); } Loading lib/Travelynx/Model/InTransit.pm +107 −2 Original line number Diff line number Diff line package Travelynx::Model::InTransit; # Copyright (C) 2020 Daniel Friesel # # SPDX-License-Identifier: AGPL-3.0-or-later Loading Loading @@ -69,6 +70,15 @@ sub delete { $db->delete( 'in_transit', { user_id => $uid } ); } sub delete_incomplete_checkins { my ( $self, %opt ) = @_; my $db = $opt{db} // $self->{pg}->db; return $db->delete( 'in_transit', { checkin_time => { '<', $opt{earlier_than} } } )->rows; } sub get { my ( $self, %opt ) = @_; Loading @@ -89,6 +99,13 @@ sub get { return $res->hash; } sub get_all_active { my ( $self, %opt ) = @_; my $db = $opt{db} // $self->{pg}->db; return $db->select( 'in_transit_str', '*', { cancelled => 0 } ) ->hashes->each; } sub get_checkout_station_id { my ( $self, %opt ) = @_; Loading Loading @@ -252,6 +269,94 @@ sub unset_arrival_data { ); } sub update_departure { my ( $self, %opt ) = @_; my $uid = $opt{uid}; my $db = $opt{db} // $self->{pg}->db; my $train = $opt{train}; my $json = JSON->new; # selecting on user_id and train_no avoids a race condition if a user checks # into a new train while we are fetching data for their previous journey. In # this case, the new train would receive data from the previous journey. $db->update( 'in_transit', { dep_platform => $train->platform, real_departure => $train->departure, route => $json->encode( $opt{route} ), messages => $json->encode( [ map { [ $_->[0]->epoch, $_->[1] ] } $train->messages ] ), }, { user_id => $uid, train_no => $train->train_no } ); } sub update_departure_cancelled { my ( $self, %opt ) = @_; my $uid = $opt{uid}; my $db = $opt{db} // $self->{pg}->db; my $dep_eva = $opt{dep_eva}; my $arr_eva = $opt{arr_eva}; my $train = $opt{train}; # depending on the amount of users in transit, some time may # have passed between fetching $entry from the database and # now. Ensure that the user is still checked into this train # by selecting on uid, train no, and checkin/checkout station ID. my $rows = $db->update( 'in_transit', { cancelled => 1, }, { user_id => $uid, train_no => $train->train_no, checkin_station_id => $dep_eva, checkout_station_id => $arr_eva, } )->rows; return $rows; } sub update_arrival { my ( $self, %opt ) = @_; my $uid = $opt{uid}; my $db = $opt{db} // $self->{pg}->db; my $arr_eva = $opt{arr_eva}; my $train = $opt{train}; my $json = JSON->new; # selecting on user_id, train_no and checkout_station_id avoids a # race condition when a user checks into a new train or changes # their destination station while we are fetching times based on no # longer valid database entries. my $rows = $db->update( 'in_transit', { arr_platform => $train->platform, sched_arrival => $train->sched_arrival, real_arrival => $train->arrival, route => $json->encode( $opt{route} ), messages => $json->encode( [ map { [ $_->[0]->epoch, $_->[1] ] } $train->messages ] ), }, { user_id => $uid, train_no => $train->train_no, checkout_station_id => $arr_eva, } )->rows; return $rows; } sub update_data { my ( $self, %opt ) = @_; Loading Loading
lib/Travelynx/Command/work.pm +32 −107 Original line number Diff line number Diff line Loading @@ -21,18 +21,14 @@ sub run { my $checkin_deadline = $now->clone->subtract( hours => 48 ); my $json = JSON->new; my $db = $self->app->pg->db; my $num_incomplete = $self->app->in_transit->delete_incomplete_checkins( earlier_than => $checkin_deadline ); my $res = $db->delete( 'in_transit', { checkin_time => { '<', $checkin_deadline } } ); if ( my $rows = $res->rows ) { $self->app->log->debug("Removed ${rows} incomplete checkins"); if ($num_incomplete) { $self->app->log->debug("Removed ${num_incomplete} incomplete checkins"); } for my $entry ( $db->select( 'in_transit_str', '*', { cancelled => 0 } )->hashes->each ) { for my $entry ( $self->app->in_transit->get_all_active ) { my $uid = $entry->{user_id}; my $dep = $entry->{dep_eva}; Loading Loading @@ -63,61 +59,26 @@ sub run { die("could not find train $train_id at $dep\n"); } # selecting on user_id and train_no avoids a race condition when # a user checks into a new train while we are fetching data for # their previous journey. In this case, the new train would # receive data from the previous journey. $db->update( 'in_transit', { dep_platform => $train->platform, real_departure => $train->departure, route => $json->encode( [ $self->app->iris->route_diff($train) ] ), messages => $json->encode( [ map { [ $_->[0]->epoch, $_->[1] ] } $train->messages ] ), }, { user_id => $uid, train_no => $train->train_no } $self->app->in_transit->update_departure( uid => $uid, train => $train, route => [ $self->app->iris->route_diff($train) ] ); if ( $train->departure_is_cancelled and $arr ) { my $checked_in = $self->app->in_transit->update_departure_cancelled( uid => $uid, train => $train, dep_eva => $dep, arr_eva => $arr, ); # depending on the amount of users in transit, some time may # have passed between fetching $entry from the database and # now. Ensure that the user is still checked into this train # before calling checkout to mark the cancellation. if ( $db->select( 'in_transit', 'count(*) as count', { user_id => $uid, train_no => $train->train_no, checkin_station_id => $dep, checkout_station_id => $arr, } )->hash->{count} ) { $db->update( 'in_transit', { cancelled => 1, }, { user_id => $uid, train_no => $train->train_no, checkin_station_id => $dep, checkout_station_id => $arr, } ); # now. Only check out if the user is still checked into this # train. if ($checked_in) { # check out (adds a cancelled journey and resets journey state # to checkin Loading Loading @@ -173,50 +134,15 @@ sub run { return; } # selecting on user_id, train_no and checkout_station_id avoids a # race condition when a user checks into a new train or changes # their destination station while we are fetching times based on no # longer valid database entries. $db->update( 'in_transit', { arr_platform => $train->platform, sched_arrival => $train->sched_arrival, real_arrival => $train->arrival, route => $json->encode( [ $self->app->iris->route_diff($train) ] ), messages => $json->encode( [ map { [ $_->[0]->epoch, $_->[1] ] } $train->messages ] ), }, { user_id => $uid, train_no => $train->train_no, checkout_station_id => $arr } my $checked_in = $self->app->in_transit->update_arrival( uid => $uid, train => $train, route => [ $self->app->iris->route_diff($train) ], arr_eva => $arr, ); if ( $train->arrival_is_cancelled ) { # depending on the amount of users in transit, some time may # have passed between fetching $entry from the database and # now. Ensure that the user is still checked into this train # before calling checkout to mark the cancellation. if ( $db->select( 'in_transit', 'count(*) as count', { user_id => $uid, train_no => $train->train_no, checkout_station_id => $arr } )->hash->{count} ) { if ( $checked_in and $train->arrival_is_cancelled ) { # check out (adds a cancelled journey and resets journey state # to destination selection) $self->app->checkout( Loading @@ -225,7 +151,6 @@ sub run { uid => $uid ); } } else { $self->app->add_route_timestamps( $uid, $train, 0 ); } Loading
lib/Travelynx/Model/InTransit.pm +107 −2 Original line number Diff line number Diff line package Travelynx::Model::InTransit; # Copyright (C) 2020 Daniel Friesel # # SPDX-License-Identifier: AGPL-3.0-or-later Loading Loading @@ -69,6 +70,15 @@ sub delete { $db->delete( 'in_transit', { user_id => $uid } ); } sub delete_incomplete_checkins { my ( $self, %opt ) = @_; my $db = $opt{db} // $self->{pg}->db; return $db->delete( 'in_transit', { checkin_time => { '<', $opt{earlier_than} } } )->rows; } sub get { my ( $self, %opt ) = @_; Loading @@ -89,6 +99,13 @@ sub get { return $res->hash; } sub get_all_active { my ( $self, %opt ) = @_; my $db = $opt{db} // $self->{pg}->db; return $db->select( 'in_transit_str', '*', { cancelled => 0 } ) ->hashes->each; } sub get_checkout_station_id { my ( $self, %opt ) = @_; Loading Loading @@ -252,6 +269,94 @@ sub unset_arrival_data { ); } sub update_departure { my ( $self, %opt ) = @_; my $uid = $opt{uid}; my $db = $opt{db} // $self->{pg}->db; my $train = $opt{train}; my $json = JSON->new; # selecting on user_id and train_no avoids a race condition if a user checks # into a new train while we are fetching data for their previous journey. In # this case, the new train would receive data from the previous journey. $db->update( 'in_transit', { dep_platform => $train->platform, real_departure => $train->departure, route => $json->encode( $opt{route} ), messages => $json->encode( [ map { [ $_->[0]->epoch, $_->[1] ] } $train->messages ] ), }, { user_id => $uid, train_no => $train->train_no } ); } sub update_departure_cancelled { my ( $self, %opt ) = @_; my $uid = $opt{uid}; my $db = $opt{db} // $self->{pg}->db; my $dep_eva = $opt{dep_eva}; my $arr_eva = $opt{arr_eva}; my $train = $opt{train}; # depending on the amount of users in transit, some time may # have passed between fetching $entry from the database and # now. Ensure that the user is still checked into this train # by selecting on uid, train no, and checkin/checkout station ID. my $rows = $db->update( 'in_transit', { cancelled => 1, }, { user_id => $uid, train_no => $train->train_no, checkin_station_id => $dep_eva, checkout_station_id => $arr_eva, } )->rows; return $rows; } sub update_arrival { my ( $self, %opt ) = @_; my $uid = $opt{uid}; my $db = $opt{db} // $self->{pg}->db; my $arr_eva = $opt{arr_eva}; my $train = $opt{train}; my $json = JSON->new; # selecting on user_id, train_no and checkout_station_id avoids a # race condition when a user checks into a new train or changes # their destination station while we are fetching times based on no # longer valid database entries. my $rows = $db->update( 'in_transit', { arr_platform => $train->platform, sched_arrival => $train->sched_arrival, real_arrival => $train->arrival, route => $json->encode( $opt{route} ), messages => $json->encode( [ map { [ $_->[0]->epoch, $_->[1] ] } $train->messages ] ), }, { user_id => $uid, train_no => $train->train_no, checkout_station_id => $arr_eva, } )->rows; return $rows; } sub update_data { my ( $self, %opt ) = @_; Loading