e3a3e460fe4ca5cd5d1f281b72b599fc444b9b01 hiram Thu Apr 18 13:10:28 2019 -0700 adding measureTiming and jsonOutputArrays plus split chrom testing refs #18869 diff --git src/hg/hubApi/tests/jsonConsumer.pl src/hg/hubApi/tests/jsonConsumer.pl index abaa789..cf5a32d 100755 --- src/hg/hubApi/tests/jsonConsumer.pl +++ src/hg/hubApi/tests/jsonConsumer.pl @@ -1,61 +1,67 @@ #!/usr/bin/env perl use strict; use warnings; use HTTP::Tiny; use Time::HiRes; use JSON; use Getopt::Long; my $http = HTTP::Tiny->new(); # my $server = 'https://apibeta.soe.ucsc.edu'; # my $server = 'https://api-test.gi.ucsc.edu'; my $server = 'https://hgwdev-api.gi.ucsc.edu'; # my $server = 'https://hgwbeta.soe.ucsc.edu/cgi-bin/hubApi'; -my $global_headers = { 'Content-Type' => 'application/json' }; -my $last_request_time = Time::HiRes::time(); -my $request_count = 0; +my $globalHeaders = { 'Content-Type' => 'application/json' }; +my $lastRequestTime = Time::HiRes::time(); +my $processStartTime = Time::HiRes::time(); +my $requestCount = 0; ############################################################################## # command line options my $endpoint = ""; my $hubUrl = ""; my $genome = ""; my $db = ""; my $track = ""; my $chrom = ""; my $start = ""; my $end = ""; my $test0 = 0; my $debug = 0; my $trackLeavesOnly = 0; -my $maxItemsOutput = ""; +my $measureTiming = 0; +my $jsonOutputArrays = 0; +my $maxItemsOutput = 0; ############################################################################## sub usage() { printf STDERR "usage: ./jsonConsumer.pl [arguments]\n"; printf STDERR "arguments: -test0 - perform test of /list/publicHubs and /list/ucscGenomes endpoints -hubUrl= - use the URL to access the track or assembly hub -db= - use one of the UCSC databases for data access -track= - specify a single track in a hub or database -chrom= - restrict the operation to a single chromosome -start= - restrict the operation to a range, use both start and end -end= - restrict the operation to a range, use both start and end -maxItemsOutput= - limit output to this number of items. Default 1,000 maximum allowed 1,000,000 +-trackLeavesOnly - for list tracks function, no containers listed +-measureTimeing - turn on timing measurement +-debug - turn on debugging business -endpoint= - where is one of the following: /list/publicHubs - provide a listing of all available public hubs /list/ucscGenomes - provide a listing of all available UCSC genomes /list/hubGenomes - list genomes from a specified hub (with hubUrl=...) /list/tracks - list data tracks available in specified hub or database genome /list/chromosomes - list chromosomes from specified data track /getData/sequence - return sequence from specified hub or database genome /getData/track - return data from specified track in hub or database genome "; } ######################################################################### # generic output of a hash pointer sub hashOutput($) { my ($hashRef) = @_; @@ -77,94 +83,97 @@ } } } ######################################################################### ############################################################################## ### ### these functions were copied from Ensembl HTTP::Tiny example code: ### https://github.com/Ensembl/ensembl-rest/wiki/Example-Perl-Client ### ############################################################################## ############################################################################## sub performJsonAction { my ($endpoint, $parameters) = @_; - my $headers = $global_headers; + my $headers = $globalHeaders; my $content = performRestAction($endpoint, $parameters, $headers); return {} unless $content; my $json = decode_json($content); return $json; } ############################################################################## sub performRestAction { my ($endpoint, $parameters, $headers) = @_; $parameters ||= {}; $headers ||= {}; $headers->{'Content-Type'} = 'application/json' unless exists $headers->{'Content-Type'}; - if($request_count == 15) { # check every 15 - my $current_time = Time::HiRes::time(); - my $diff = $current_time - $last_request_time; + if($requestCount == 15) { # check every 15 + my $currentTime = Time::HiRes::time(); + my $diff = $currentTime - $lastRequestTime; # if less than a second then sleep for the remainder of the second if($diff < 1) { Time::HiRes::sleep(1-$diff); } # reset - $last_request_time = Time::HiRes::time(); - $request_count = 0; + $lastRequestTime = Time::HiRes::time(); + $requestCount = 0; } $endpoint =~ s#^/##; my $url = "$server/$endpoint"; if(%{$parameters}) { my @params; foreach my $key (keys %{$parameters}) { my $value = $parameters->{$key}; push(@params, "$key=$value"); } my $param_string = join(';', @params); $url.= '?'.$param_string; } if ($debug) { $url .= ";debug=1"; } + if ($measureTiming) { $url .= ";measureTiming=1"; } + if ($jsonOutputArrays) { $url .= ";jsonOutputArrays=1"; } + if ($maxItemsOutput) { $url .= ";maxItemsOutput=$maxItemsOutput"; } printf STDERR "### '%s'\n", $url; my $response = $http->get($url, {headers => $headers}); my $status = $response->{status}; if(!$response->{success}) { # Quickly check for rate limit exceeded & Retry-After (lowercase due to our client) if($status == 429 && exists $response->{headers}->{'retry-after'}) { my ($status, $reason) = ($response->{status}, $response->{reason}); my $retry = $response->{headers}->{'retry-after'}; printf STDERR "Failed for $endpoint! Status code: ${status}. Reason: ${reason}, retry-after: $retry seconds\n"; # hashOutput($response->{headers}); Time::HiRes::sleep($retry); # After sleeping see that we re-request return performRestAction($endpoint, $parameters, $headers); } else { my ($status, $reason) = ($response->{status}, $response->{reason}); # die "Failed for $endpoint! Status code: ${status}. Reason: ${reason}\n"; printf STDERR "Failed for $endpoint! Status code: ${status}. Reason: ${reason}\n"; # hashOutput($response->{headers}); # hashOutput($response->{content}); # printf STDERR "'%s'\n", $response->{content}; # printf STDERR "'%s'\n", $response->{headers}; return return $response->{content}; } } - $request_count++; + $requestCount++; if(length $response->{content}) { return $response->{content}; } return; } ############################################################################# sub columnNames($) { my ($nameArray) = @_; if (ref($nameArray) ne "ARRAY") { printf "ERROR: do not have an array reference in columnNames\n"; } else { printf "### Column names in table return:\n"; my $i = 0; foreach my $name (@$nameArray) { @@ -309,31 +318,31 @@ } if (length($track)) { $parameters{"track"} = "$track"; } if (length($chrom)) { $parameters{"chrom"} = "$chrom"; } if (length($start)) { $parameters{"start"} = "$start"; $parameters{"end"} = "$end"; } $jsonReturn = performJsonAction($endpoint, \%parameters); $errReturn = 1 if (defined ($jsonReturn->{'error'})); printf "%s", $json->pretty->encode( $jsonReturn ); } else { - printf STDERR "# TBD: '%s'\n", $endpoint; + printf STDERR "# endpoint not supported at this time: '%s'\n", $endpoint; } } else { printf STDERR "ERROR: no endpoint given ?\n"; exit 255; } return $errReturn; } # sub processEndPoint() ########################################################################### ### test /list/publicHubs and /list/ucscGenomes sub test0() { my $json = JSON->new; my $jsonReturn = {}; @@ -387,49 +396,62 @@ if (exists($ucscGenomes->{'hg38'})) { my $hg38 = $ucscGenomes->{'hg38'}; printf "### hg38/Human information\n"; foreach my $key (sort keys %$hg38) { printf "\"%s\"\t\"%s\"\n", $key, $hg38->{$key}; } } } } elsif (ref($jsonReturn) eq "ARRAY") { printf "ERROR: top level returns ARRAY of size: %d\n", scalar(@$jsonReturn); printf "should have been a HASH to the ucscGenomes\n"; } } # sub test0() +sub elapsedTime() { +if ($measureTiming) { + my $endTime = Time::HiRes::time(); + my $et = $endTime - $processStartTime; + printf STDERR "# procesing time: %.3fs\n", $et; +} +} + ############################################################################# ### main() ############################################################################# my $argc = scalar(@ARGV); GetOptions ("hubUrl=s" => \$hubUrl, "endpoint=s" => \$endpoint, "genome=s" => \$genome, "db=s" => \$db, "track=s" => \$track, "chrom=s" => \$chrom, "start=s" => \$start, "end=s" => \$end, "test0" => \$test0, "debug" => \$debug, "trackLeavesOnly" => \$trackLeavesOnly, + "measureTiming" => \$measureTiming, + "jsonOutputArrays" => \$jsonOutputArrays, "maxItemsOutput=s" => \$maxItemsOutput) or die "Error in command line arguments\n"; if ($test0) { test0; + elapsedTime(); exit 0; } if ($argc > 0) { if (processEndPoint()) { + elapsedTime(); exit 255; } else { + elapsedTime(); exit 0; } } usage();