Commit b3b0a055 authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

improve get_user_travels performance, most notably when rendering map

only create DateTime objects when needed
parent 9782cee5
Loading
Loading
Loading
Loading
+52 −47
Original line number Diff line number Diff line
@@ -785,6 +785,7 @@ sub startup {
			my $journey = $self->get_journey(
				db            => $db,
				journey_id    => $journey_id,
				with_datetime => 1,
			);

			eval {
@@ -1504,8 +1505,8 @@ sub startup {
			# are really deleting the right journey and the user isn't just
			# playing around with POST requests.
			if (   $journey->{id} != $journey_id
				or $journey->{checkin}->epoch != $checkin_epoch
				or $journey->{checkout}->epoch != $checkout_epoch )
				or $journey->{checkin_ts} != $checkin_epoch
				or $journey->{checkout_ts} != $checkout_epoch )
			{
				return 'Invalid journey data';
			}
@@ -1527,7 +1528,8 @@ sub startup {
			}

			if ( $rows == 1 ) {
				$self->invalidate_stats_cache( $journey->{rt_departure} );
				$self->invalidate_stats_cache(
					epoch_to_dt( $journey->{rt_dep_ts} ) );
				return undef;
			}
			return sprintf( 'Deleted %d rows, expected 1', $rows );
@@ -2382,19 +2384,29 @@ sub startup {
					line         => $entry->{train_line},
					no           => $entry->{train_no},
					from_name    => $entry->{dep_name},
					checkin         => epoch_to_dt( $entry->{checkin_ts} ),
					sched_departure => epoch_to_dt( $entry->{sched_dep_ts} ),
					rt_departure    => epoch_to_dt( $entry->{real_dep_ts} ),
					checkin_ts   => $entry->{checkin_ts},
					sched_dep_ts => $entry->{sched_dep_ts},
					rt_dep_ts    => $entry->{real_dep_ts},
					to_name      => $entry->{arr_name},
					checkout        => epoch_to_dt( $entry->{checkout_ts} ),
					sched_arrival   => epoch_to_dt( $entry->{sched_arr_ts} ),
					rt_arrival      => epoch_to_dt( $entry->{real_arr_ts} ),
					checkout_ts  => $entry->{checkout_ts},
					sched_arr_ts => $entry->{sched_arr_ts},
					rt_arr_ts    => $entry->{real_arr_ts},
					messages     => $entry->{messages},
					route        => $entry->{route},
					edited       => $entry->{edited},
					user_data    => $entry->{user_data},
				};

				if ( $opt{with_datetime} ) {
					$ref->{checkin} = epoch_to_dt( $ref->{checkin_ts} );
					$ref->{sched_departure}
					  = epoch_to_dt( $ref->{sched_dep_ts} );
					$ref->{rt_departure}  = epoch_to_dt( $ref->{rt_dep_ts} );
					$ref->{checkout}      = epoch_to_dt( $ref->{checkout_ts} );
					$ref->{sched_arrival} = epoch_to_dt( $ref->{sched_arr_ts} );
					$ref->{rt_arrival}    = epoch_to_dt( $ref->{rt_arr_ts} );
				}

				if ( $opt{verbose} ) {
					$ref->{cancelled} = $entry->{cancelled};
					my @parsed_messages;
@@ -2404,13 +2416,12 @@ sub startup {
					}
					$ref->{messages} = [ reverse @parsed_messages ];
					$ref->{sched_duration}
					  = $ref->{sched_arrival}->epoch
					  ? $ref->{sched_arrival}->epoch
					  - $ref->{sched_departure}->epoch
					  = $ref->{sched_arr_ts}
					  ? $ref->{sched_arr_ts} - $ref->{sched_dep_ts}
					  : undef;
					$ref->{rt_duration}
					  = $ref->{rt_arrival}->epoch
					  ? $ref->{rt_arrival}->epoch - $ref->{rt_departure}->epoch
					  = $ref->{rt_arr_ts}
					  ? $ref->{rt_arr_ts} - $ref->{rt_dep_ts}
					  : undef;
					my ( $km_route, $km_beeline, $skip )
					  = $self->get_travel_distance( $ref->{from_name},
@@ -2960,7 +2971,7 @@ sub startup {
			my $num_journeys     = 0;
			my @inconsistencies;

			my $next_departure = epoch_to_dt(0);
			my $next_departure = 0;

			for my $journey (@journeys) {
				$num_trains++;
@@ -2974,42 +2985,36 @@ sub startup {
				if ( $journey->{rt_duration} and $journey->{rt_duration} > 0 ) {
					$min_travel_real += $journey->{rt_duration} / 60;
				}
				if ( $journey->{sched_departure} and $journey->{rt_departure} )
				{
				if ( $journey->{sched_dep_ts} and $journey->{rt_dep_ts} ) {
					$delay_dep
					  += (  $journey->{rt_departure}->epoch
						  - $journey->{sched_departure}->epoch ) / 60;
					  += ( $journey->{rt_dep_ts} - $journey->{sched_dep_ts} )
					  / 60;
				}
				if ( $journey->{sched_arrival} and $journey->{rt_arrival} ) {
				if ( $journey->{sched_arr_ts} and $journey->{rt_arr_ts} ) {
					$delay_arr
					  += (  $journey->{rt_arrival}->epoch
						  - $journey->{sched_arrival}->epoch ) / 60;
					  += ( $journey->{rt_arr_ts} - $journey->{sched_arr_ts} )
					  / 60;
				}

				# Note that journeys are sorted from recent to older entries
				if (    $journey->{rt_arrival}
					and $next_departure->epoch
					and $next_departure->epoch - $journey->{rt_arrival}->epoch
					< ( 60 * 60 ) )
				{
					if (
						$next_departure->epoch - $journey->{rt_arrival}->epoch
						< 0 )
				if (    $journey->{rt_arr_ts}
					and $next_departure
					and $next_departure - $journey->{rt_arr_ts} < ( 60 * 60 ) )
				{
					if ( $next_departure - $journey->{rt_arr_ts} < 0 ) {
						push( @inconsistencies,
							$next_departure->strftime('%d.%m.%Y %H:%M') );
							epoch_to_dt($next_departure)
							  ->strftime('%d.%m.%Y %H:%M') );
					}
					else {
						$interchange_real
						  += (  $next_departure->epoch
							  - $journey->{rt_arrival}->epoch )
						  / 60;
						  += ( $next_departure - $journey->{rt_arr_ts} ) / 60;
					}
				}
				else {
					$num_journeys++;
				}
				$next_departure = $journey->{rt_departure};
				$next_departure = $journey->{rt_dep_ts};
			}
			return {
				km_route             => $km_route,
+19 −15
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ sub mark_substitute_connection {
	my @substitute_candidates = reverse $self->get_user_travels(
		after  => $journey->{sched_departure}->clone->subtract( hours => 1 ),
		before => $journey->{sched_departure}->clone->add( hours => 12 ),
		with_datetime => 1,
	);

	my ( $first_substitute, $last_substitute );
@@ -76,8 +77,7 @@ sub mark_substitute_connection {
		$journey->{from_substitute} = $first_substitute;
		$journey->{to_substitute}   = $last_substitute;
		$journey->{substitute_delay}
		  = (   $last_substitute->{rt_arrival}->epoch
			  - $journey->{sched_arrival}->epoch ) / 60;
		  = ( $last_substitute->{rt_arr_ts} - $journey->{sched_ar_ts} ) / 60;
	}
}

@@ -89,7 +89,8 @@ sub list_candidates {

	my @journeys = $self->get_user_travels(
		after         => $range_start,
		before => $now
		before        => $now,
		with_datetime => 1,
	);
	@journeys = grep { $_->{sched_arrival}->epoch and $_->{rt_arrival}->epoch }
	  @journeys;
@@ -114,7 +115,8 @@ sub list_candidates {
	my @cancelled = $self->get_user_travels(
		after         => $range_start,
		before        => $now,
		cancelled => 1
		cancelled     => 1,
		with_datetime => 1,
	);
	for my $journey (@cancelled) {

@@ -126,8 +128,8 @@ sub list_candidates {
		$self->mark_substitute_connection($journey);

		if ( not $journey->{has_substitute}
			or $journey->{to_substitute}->{rt_arrival}->epoch
			- $journey->{sched_arrival}->epoch >= 3600 )
			or $journey->{to_substitute}->{rt_arr_ts} - $journey->{sched_arr_ts}
			>= 3600 )
		{
			push( @journeys, $journey );
		}
@@ -165,6 +167,7 @@ sub generate {
		uid           => $uid,
		journey_id    => $journey_id,
		verbose       => 1,
		with_datetime => 1,
	);

	if ( not $journey ) {
@@ -187,7 +190,8 @@ sub generate {
		my @connections = $self->get_user_travels(
			uid           => $uid,
			after         => $journey->{rt_arrival},
			before => $journey->{rt_arrival}->clone->add( hours => 2 )
			before        => $journey->{rt_arrival}->clone->add( hours => 2 ),
			with_datetime => 1,
		);
		if (@connections) {
			$self->mark_if_missed_connection( $journey, $connections[-1] );
+24 −21
Original line number Diff line number Diff line
@@ -397,7 +397,10 @@ sub redirect_to_station {

sub cancelled {
	my ($self) = @_;
	my @journeys = $self->get_user_travels( cancelled => 1 );
	my @journeys = $self->get_user_travels(
		cancelled     => 1,
		with_datetime => 1
	);

	$self->respond_to(
		json => { json => [@journeys] },
@@ -419,7 +422,6 @@ sub map_history {

	my $location = $self->app->coordinates_by_station;

# TODO create map-specific get_user_travels function returning EVA/DS100 station codes?
	my @journeys = $self->get_user_travels;

	if ( not @journeys ) {
@@ -428,8 +430,6 @@ sub map_history {
			with_map            => 1,
			station_coordinates => [],
			station_pairs       => [],
			range_from          => 0,
			range_to            => 0,
		);
		return;
	}
@@ -494,8 +494,6 @@ sub map_history {
		with_map            => 1,
		station_coordinates => \@station_coordinates,
		station_pairs       => \@station_pairs,
		range_from          => $first_departure,
		range_to            => $last_departure,
	);
}

@@ -515,7 +513,7 @@ sub yearly_history {
	# -> Limit time range to avoid accidental DoS.
	if ( not( $year =~ m{ ^ [0-9]{4} $ }x and $year > 1990 and $year < 2100 ) )
	{
		@journeys = $self->get_user_travels;
		@journeys = $self->get_user_travels( with_datetime => 1 );
	}
	else {
		my $interval_start = DateTime->new(
@@ -530,7 +528,8 @@ sub yearly_history {
		my $interval_end = $interval_start->clone->add( years => 1 );
		@journeys = $self->get_user_travels(
			after         => $interval_start,
			before => $interval_end
			before        => $interval_end,
			with_datetime => 1
		);
		$stats = $self->get_journey_stats( year => $year );
	}
@@ -572,7 +571,7 @@ sub monthly_history {
			and $month < 13 )
	  )
	{
		@journeys = $self->get_user_travels;
		@journeys = $self->get_user_travels( with_datetime => 1 );
	}
	else {
		my $interval_start = DateTime->new(
@@ -587,7 +586,8 @@ sub monthly_history {
		my $interval_end = $interval_start->clone->add( months => 1 );
		@journeys = $self->get_user_travels(
			after         => $interval_start,
			before => $interval_end
			before        => $interval_end,
			with_datetime => 1
		);
		$stats = $self->get_journey_stats(
			year  => $year,
@@ -635,6 +635,7 @@ sub journey_details {
		uid           => $uid,
		journey_id    => $journey_id,
		verbose       => 1,
		with_datetime => 1,
	);

	if ($journey) {
@@ -670,7 +671,8 @@ sub edit_journey {

	my $journey = $self->get_journey(
		uid           => $uid,
		journey_id => $journey_id
		journey_id    => $journey_id,
		with_datetime => 1,
	);

	if ( not $journey ) {
@@ -735,7 +737,8 @@ sub edit_journey {
				uid           => $uid,
				db            => $db,
				journey_id    => $journey_id,
				verbose    => 1
				verbose       => 1,
				with_datetime => 1,
			);
			$error = $self->journey_sanity_check($journey);
		}
+4 −0
Original line number Diff line number Diff line
@@ -237,6 +237,10 @@ $t->get_ok('/history/2018')->status_is(200)->content_like(qr{62 km})
  ->content_like(qr{Bei Abfahrt: 00:00 Stunden})
  ->content_like(qr{Bei Ankunft: 00:00 Stunden});

$t->get_ok('/history/map')->status_is(200)
  ->content_like(qr{\[\[51.956[^,]*,7.635[^]]*\],'M.nster\(Westf\)Hbf'\],})
  ->content_like(qr{\[\[51.504[^,]*,7.102[^]]*\],'Gelsenkirchen Hbf'\]});

$csrf_token
  = $t->ua->get('/journey/add')->res->dom->at('input[name=csrf_token]')
  ->attr('value');
+1 −1
Original line number Diff line number Diff line
<div class="row">
	<div class="col s12">
		% if (@{$station_coordinates}) {
			Zugfahrten zwischen <%= $range_from->strftime('%d.%m.%Y') %> und <%= $range_to->strftime('%d.%m.%Y') %>
			Alle bisherigen Zugfahrten
		% }
		% else {
			Keine Zugfahrten gefunden.
Loading