Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: default redis url to empty and handle reconnects #7540

Merged
merged 7 commits into from
Oct 14, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
104 changes: 86 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::Redit> is handling pushing info to Redis
stephanegigandet marked this conversation as resolved.
Show resolved Hide resolved
to communicate updates to openfoodfacts-search instance

=cut

package ProductOpener::Redis;

use ProductOpener::PerlStandards;
Expand All @@ -14,39 +25,96 @@ 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;

=head2 $redis_client
The connection to redis
=cut
my $redis_client;


sub init_redis() {
=head2 init_redis($is_reconnect=0)

$log->debug("init_redis", {redis_url_env => $ENV{REDIS_URL}, redis_url => $ProductOpener::Config2::redis_url})
init $redis_client or re-init it if we where disconnected

it is uses ProductOpener::Config2::redis_url

=head3 Arguments

=head4 bool $is_reconnect

This is informative.
If true we will display a warning if we have no redis_url.

=cut

sub init_redis($is_reconnect=0) {
$log->debug("init_redis", {redis_url => $redis_url})
if $log->is_debug();

$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;
if (((! defined $redis_url) || ($redis_url eq "")) && ! $is_reconnect) {
$log->warn("Redis URL not provided for search indexing") if $log->is_warn();
}
my $redis_client;
eval {$redis_client = Redis::Client->new(host => $ProductOpener::Config2::redis_url);};
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();
$redis_client = -1; # this ask for eventual reconnection
alexgarel marked this conversation as resolved.
Show resolved Hide resolved
}
else {
return $redis_client;
}
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)) {
eval {$redis_client->rpush('search_import_queue', $product_ref->{code});};

if (!$redis_url) {
# off search not activated
return;
}

my $error = "";
if ((!defined $redis_client) || ($redis_client == -1)) {
# we where deconnected, try again
$log->info("Trying to reconnect to redis");
init_redis(defined $redis_client);
}
if (defined($redis_client) && ($redis_client != -1)) {
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 = -1;
}

return;
}


1;