From 2ca4a50194108d378b961fb8ddc9a0455933d96d Mon Sep 17 00:00:00 2001
From: Daniel Friesel <derf@finalrewind.org>
Date: Wed, 16 Sep 2020 17:21:49 +0200
Subject: all requests but IRIS are async now

---
 lib/DBInfoscreen.pm                         |  11 ++-
 lib/DBInfoscreen/Controller/Stationboard.pm |  23 +++--
 lib/DBInfoscreen/Controller/Wagenreihung.pm |  43 +--------
 lib/DBInfoscreen/Helper/Wagonorder.pm       | 139 +++++++++++++++++++++-------
 4 files changed, 130 insertions(+), 86 deletions(-)

diff --git a/lib/DBInfoscreen.pm b/lib/DBInfoscreen.pm
index 3b3d5c1..155a6d0 100644
--- a/lib/DBInfoscreen.pm
+++ b/lib/DBInfoscreen.pm
@@ -116,11 +116,12 @@ sub startup {
 		wagonorder => sub {
 			my ($self) = @_;
 			state $hafas = DBInfoscreen::Helper::Wagonorder->new(
-				log        => $self->app->log,
-				cache      => $self->app->cache_iris_main,
-				root_url   => $self->url_for('/')->to_abs,
-				user_agent => $self->ua,
-				version    => $VERSION,
+				log            => $self->app->log,
+				main_cache     => $self->app->cache_iris_main,
+				realtime_cache => $self->app->cache_iris_rt,
+				root_url       => $self->url_for('/')->to_abs,
+				user_agent     => $self->ua,
+				version        => $VERSION,
 			);
 		}
 	);
diff --git a/lib/DBInfoscreen/Controller/Stationboard.pm b/lib/DBInfoscreen/Controller/Stationboard.pm
index 3b93ac3..1ea238c 100644
--- a/lib/DBInfoscreen/Controller/Stationboard.pm
+++ b/lib/DBInfoscreen/Controller/Stationboard.pm
@@ -412,13 +412,6 @@ sub render_train {
 		)
 	];
 
-	if ( $departure->{wr_link}
-		and
-		not $self->wagonorder->is_available( $result, $departure->{wr_link} ) )
-	{
-		$departure->{wr_link} = undef;
-	}
-
 	my $linetype = 'bahn';
 	if ( $departure->{train_type} eq 'S' ) {
 		$linetype = 'sbahn';
@@ -446,6 +439,22 @@ sub render_train {
 
 	$self->render_later;
 
+	# if wagonorder->is_available_p takes longer than get_route_timestamps_p,
+	# we'll have a useless (non-working) wagonorder link. That's okay.
+	if ( $departure->{wr_link} ) {
+		$self->wagonorder->is_available_p( $result, $departure->{wr_link} )
+		  ->then(
+			sub {
+				# great!
+				return;
+			},
+			sub {
+				$departure->{wr_link} = undef;
+				return;
+			}
+		)->wait;
+	}
+
 	$self->hafas->get_route_timestamps_p( train => $result )->then(
 		sub {
 			my ( $route_ts, $route_info, $trainsearch ) = @_;
diff --git a/lib/DBInfoscreen/Controller/Wagenreihung.pm b/lib/DBInfoscreen/Controller/Wagenreihung.pm
index 7b59227..ecdb129 100644
--- a/lib/DBInfoscreen/Controller/Wagenreihung.pm
+++ b/lib/DBInfoscreen/Controller/Wagenreihung.pm
@@ -4,53 +4,12 @@ use Mojo::Base 'Mojolicious::Controller';
 # Copyright (C) 2011-2019 Daniel Friesel <derf+dbf@finalrewind.org>
 # License: 2-Clause BSD
 
-use Encode qw(decode);
-use JSON;
-use Mojo::Promise;
 use Travel::Status::DE::DBWagenreihung;
 
 my $dbf_version = qx{git describe --dirty} || 'experimental';
 
 chomp $dbf_version;
 
-sub get_wagenreihung_p {
-	my ( $self, $train_no, $api_ts ) = @_;
-
-	my $url
-	  = "https://www.apps-bahn.de/wr/wagenreihung/1.0/${train_no}/${api_ts}";
-
-	my $cache = $self->app->cache_iris_rt;
-
-	my $promise = Mojo::Promise->new;
-
-	if ( my $content = $cache->thaw($url) ) {
-		$promise->resolve($content);
-		$self->app->log->debug("GET $url (cached)");
-		return $promise;
-	}
-
-	$self->ua->request_timeout(10)
-	  ->get_p( $url, { 'User-Agent' => "dbf.finalrewind.org/${dbf_version}" } )
-	  ->then(
-		sub {
-			my ($tx) = @_;
-			$self->app->log->debug("GET $url (OK)");
-			my $body = decode( 'utf-8', $tx->res->body );
-			my $json = JSON->new->decode($body);
-
-			$cache->freeze( $url, $json );
-			$promise->resolve($json);
-		}
-	)->catch(
-		sub {
-			my ($err) = @_;
-			$self->app->log->debug("GET $url (error: $err)");
-			$promise->reject($err);
-		}
-	)->wait;
-	return $promise;
-}
-
 sub wagenreihung {
 	my ($self)    = @_;
 	my $train     = $self->stash('train');
@@ -58,7 +17,7 @@ sub wagenreihung {
 
 	$self->render_later;
 
-	$self->get_wagenreihung_p( $train, $departure )->then(
+	$self->wagonorder->get_p( $train, $departure )->then(
 		sub {
 			my ($json) = @_;
 			my $wr;
diff --git a/lib/DBInfoscreen/Helper/Wagonorder.pm b/lib/DBInfoscreen/Helper/Wagonorder.pm
index 91006fc..5f0555d 100644
--- a/lib/DBInfoscreen/Helper/Wagonorder.pm
+++ b/lib/DBInfoscreen/Helper/Wagonorder.pm
@@ -4,10 +4,7 @@ use strict;
 use warnings;
 use 5.020;
 
-use DateTime;
-use Encode qw(decode encode);
-use Mojo::JSON qw(decode_json);
-use XML::LibXML;
+use Mojo::Promise;
 
 sub new {
 	my ( $class, %opt ) = @_;
@@ -23,48 +20,126 @@ sub new {
 
 }
 
-sub is_available {
+sub is_available_p {
 	my ( $self, $train, $wr_link ) = @_;
-
-	if ( $self->check_wagonorder( $train->train_no, $wr_link ) ) {
-		return 1;
-	}
-	elsif ( $train->is_wing ) {
-		my $wing = $train->wing_of;
-		if ( $self->check_wagonorder( $wing->train_no, $wr_link ) ) {
-			return 1;
+	my $promise = Mojo::Promise->new;
+
+	$self->check_wagonorder_p( $train->train_no, $wr_link )->then(
+		sub {
+			$promise->resolve;
+			return;
+		},
+		sub {
+			if ( $train->is_wing ) {
+				my $wing = $train->wing_of;
+				return $self->check_wagonorder_p( $wing->train_no, $wr_link );
+			}
+			else {
+				$promise->reject;
+				return;
+			}
 		}
-	}
-	return;
+	)->then(
+		sub {
+			$promise->resolve;
+			return;
+		},
+		sub {
+			$promise->reject;
+			return;
+		}
+	)->wait;
+
+	return $promise;
 }
 
-sub check_wagonorder {
+sub check_wagonorder_p {
 	my ( $self, $train_no, $wr_link ) = @_;
 
+	my $promise = Mojo::Promise->new;
+
 	my $url
 	  = "https://lib.finalrewind.org/dbdb/has_wagonorder/${train_no}/${wr_link}";
-	my $cache = $self->{cache};
+	my $cache = $self->{main_cache};
 
-	if ( my $content = $self->{cache}->get($url) ) {
-		return $content eq 'y' ? 1 : undef;
+	if ( my $content = $cache->get($url) ) {
+		if ( $content eq 'y' ) {
+			return $promise->resolve;
+		}
+		else {
+			return $promise->reject;
+		}
 	}
 
-	my $ua = $self->{user_agent}->request_timeout(2);
+	$self->{user_agent}->request_timeout(5)->head_p( $url => $self->{header} )
+	  ->then(
+		sub {
+			my ($tx) = @_;
+			if ( $tx->result->is_success ) {
+				$cache->set( $url, 'y' );
+				$promise->resolve;
+			}
+			else {
+				$cache->set( $url, 'n' );
+				$promise->reject;
+			}
+			return;
+		}
+	)->catch(
+		sub {
+			$cache->set( $url, 'n' );
+			$promise->reject;
+			return;
+		}
+	)->wait;
+	return $promise;
+}
+
+sub get_p {
+	my ( $self, $train_no, $api_ts ) = @_;
 
-	my $res = eval { $ua->head( $url => $self->{header} )->result };
+	my $url
+	  = "https://www.apps-bahn.de/wr/wagenreihung/1.0/${train_no}/${api_ts}";
 
-	if ($@) {
-		$self->{log}->debug("check_wagonorder($url): $@");
-		return;
-	}
-	if ( $res->is_error ) {
-		$cache->set( $url, 'n' );
-		return;
-	}
-	else {
-		$cache->set( $url, 'y' );
-		return 1;
+	my $cache = $self->{realtime_cache};
+
+	my $promise = Mojo::Promise->new;
+
+	if ( my $content = $cache->thaw($url) ) {
+		$self->{log}->debug("GET $url (cached)");
+		return $promise->resolve($content);
 	}
+
+	$self->{user_agent}->request_timeout(10)->get_p( $url => $self->{header} )
+	  ->then(
+		sub {
+			my ($tx) = @_;
+
+			if ( my $err = $tx->error ) {
+				$self->{log}->warn(
+					"wagonorder->get_p($url): HTTP $err->{code} $err->{message}"
+				);
+				$promise->reject(
+					"GET $url returned HTTP $err->{code} $err->{message}");
+				return;
+			}
+
+			$self->{log}->debug("GET $url (OK)");
+			my $json = $tx->res->json;
+
+			$cache->freeze( $url, $json );
+			$promise->resolve($json);
+			return;
+		}
+	)->catch(
+		sub {
+			my ($err) = @_;
+			$self->{log}->warn("GET $url: $err");
+			$promise->reject("GET $url: $err");
+			return;
+		}
+	)->wait;
+	return $promise;
 }
 
 1;
-- 
cgit v1.2.3