Skip to content

Commit

Permalink
fix: default redis url to empty and handle reconnects (#7540)
Browse files Browse the repository at this point in the history
As in dev people don't necessarily have openfoodfacts-search running

We also changed lib to Redis which is better maintained, and handle connection timeout.
  • Loading branch information
alexgarel committed Oct 14, 2022
1 parent 885b158 commit ced62e8
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 22 deletions.
4 changes: 3 additions & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ MONGO_INITDB_ROOT_USERNAME=root
MONGO_INITDB_ROOT_PASSWORD=test
ROBOTOFF_URL=http://robotoff.openfoodfacts.localhost:5500 # connect to Robotoff running in separate docker-compose deployment
EVENTS_URL=
REDIS_URL=searchredis:6379 # Redis runs in a separate docker-compose deployment
# use this to push products to openfoodfacts-search
# in dev: searchredis:6379 (with openfoodfacts-search running in docker in same network)
REDIS_URL=
GOOGLE_CLOUD_VISION_API_KEY=
CROWDIN_PROJECT_IDENTIFIER=
CROWDIN_PROJECT_KEY=
Expand Down
2 changes: 1 addition & 1 deletion cpanfile
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ requires 'JSON::Create';
requires 'JSON::Parse';
requires 'Data::DeepAccess';
requires 'XML::XML2JSON';
requires 'Redis::Client';
requires 'Redis';


# Mojolicious/Minion
Expand Down
4 changes: 2 additions & 2 deletions lib/ProductOpener/Products.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1179,11 +1179,11 @@ sub store_product($user_id, $product_ref, $comment) {
store("$new_data_root/products/$path/changes.sto", $changes_ref);
log_change($product_ref, $change_ref);

$log->debug("store_product - done", { code => $code, product_id => $product_id } ) if $log->is_debug();

# index for search service
push_to_search_service($product_ref);

$log->debug("store_product - done", { code => $code, product_id => $product_id } ) if $log->is_debug();

return 1;
}

Expand Down
97 changes: 79 additions & 18 deletions lib/ProductOpener/Redis.pm
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@

=head1 NAME
ProductOpener::Redis - functions to push informations to redis
=head1 DESCRIPTION
C<ProductOpener::Redis> is handling pushing info to Redis
to communicate updates to openfoodfacts-search instance
=cut

package ProductOpener::Redis;

use ProductOpener::PerlStandards;
Expand All @@ -14,36 +25,86 @@ BEGIN {

use vars @EXPORT_OK;

use Log::Any qw($log);
use ProductOpener::Config2;
use Redis::Client;
use Log::Any qw/$log/;
use ProductOpener::Config2 qw/$redis_url/;
use Redis;

sub init_redis() {
=head2 $redis_client
The connection to redis
=cut

$log->debug("init_redis", {redis_url_env => $ENV{REDIS_URL}, redis_url => $ProductOpener::Config2::redis_url})
if $log->is_debug();
my $redis_client;

$log->warn("REDIS_URL env", {redis_url => $ENV{REDIS_URL}}) if $log->is_warn();
if ($ProductOpener::Config2::redis_url eq "") {
$log->warn("Redis URL not provided for search indexing", {error => $@}) if $log->is_warn();
return;
}
my $redis_client;
eval {$redis_client = Redis::Client->new(host => $ProductOpener::Config2::redis_url);};
# tracking if we already displayed a warning
my $sent_warning_about_missing_redis_url = 0;

=head2 init_redis($is_reconnect=0)
init $redis_client or re-init it if we where disconnected
it is uses ProductOpener::Config2::redis_url
=cut

sub init_redis() {
$log->debug("init_redis", {redis_url => $redis_url})
if $log->is_debug();
eval {
$redis_client = Redis->new(
server => $redis_url,
# we don't want to sacrifice too much performance for redis problems
cnx_timeout => 1,
write_timeout => 1,
);
};
if ($@) {
$log->warn("Error connecting to Redis", {error => $@}) if $log->is_warn();
}
else {
return $redis_client;
$redis_client = undef; # this ask for eventual reconnection
}
return;
}

my $redis_client = init_redis();
=head2 push_to_search_service ($product_ref)
Inform openfoodfacts-search that a product was updated.
It uses Redis to do that.
=head3 Arguments
=head4 Product Object $product_ref
The product that was updated.
=cut

sub push_to_search_service ($product_ref) {
if (defined($redis_client)) {

if (!$redis_url) {
# off search not activated
if (!$sent_warning_about_missing_redis_url) {
$log->warn("Redis URL not provided for search indexing") if $log->is_warn();
$sent_warning_about_missing_redis_url = 1;
}
return;
}

my $error = "";
if (!defined $redis_client) {
# we where deconnected, try again
$log->info("Trying to reconnect to redis");
init_redis();
}
if (defined $redis_client) {
eval {$redis_client->rpush('search_import_queue', $product_ref->{code});};
$error = $@;
}
else {
$error = "Can't connect to redis";
}
if (!($error eq "")) {
$log->warn("Failed to push to redis", {product_code => $product_ref->{code}, error => $error})
if $log->is_warn();
# ask for eventual reconnection for next call
$redis_client = undef;
}

return;
Expand Down

0 comments on commit ced62e8

Please sign in to comment.