Skip to content

Commit

Permalink
fix: prevent concurrent notifications to be dispatched
Browse files Browse the repository at this point in the history
  • Loading branch information
warlof committed Dec 6, 2020
1 parent 9376ddc commit d0d810b
Show file tree
Hide file tree
Showing 80 changed files with 444 additions and 995 deletions.
67 changes: 67 additions & 0 deletions src/Jobs/AbstractCharacterNotification.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

/*
* This file is part of SeAT
*
* Copyright (C) 2015 to 2020 Leon Jacobs
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

namespace Seat\Notifications\Jobs;

use Seat\Eveapi\Models\Character\CharacterNotification;
use Seat\Notifications\Jobs\Middleware\CharacterNotificationThrottler;

/**
* Class AbstractCharacterNotification.
*
* @package Seat\Notifications\Notifications
*/
abstract class AbstractCharacterNotification extends AbstractNotification
{
/**
* @var \Seat\Eveapi\Models\Character\CharacterNotification
*/
protected $notification;

/**
* AbstractCharacterNotification constructor.
*
* @param \Seat\Eveapi\Models\Character\CharacterNotification $notification
*/
public function __construct(CharacterNotification $notification)
{
$this->notification = $notification;
}

/**
* @return array
*/
public function middleware()
{
return [
new CharacterNotificationThrottler,
];
}

/**
* @return int
*/
public function getNotificationId()
{
return $this->notification->notification_id;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

namespace Seat\Notifications\Notifications;

use Seat\Notifications\Jobs\AbstractNotificationJob;
namespace Seat\Notifications\Jobs;

/**
* Class AbstractNotification.
Expand Down
53 changes: 53 additions & 0 deletions src/Jobs/Middleware/CharacterNotificationThrottler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

/*
* This file is part of SeAT
*
* Copyright (C) 2015 to 2020 Leon Jacobs
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

namespace Seat\Notifications\Jobs\Middleware;

use Illuminate\Support\Facades\Redis;

/**
* Class CharacterThrottler.
*
* @package Seat\Notifications\Jobs\Middleware
*/
class CharacterNotificationThrottler
{
/**
* @param \Seat\Notifications\Jobs\AbstractCharacterNotification $job
* @param $next
*/
public function handle($job, $next)
{
$key = sprintf('%s:%d', implode(',', $job->via(true)), $job->getNotificationId());

Redis::throttle($key)->block(0)->allow(1)->every(2)->then(function () use ($job, $next) {
$next($job);
}, function () use ($job) {
logger()->debug('Notification has been queued more than once. Removing duplicates.', [
'id' => $job->getNotificationId(),
'channel' => $job->via(true),
]);

$job->delete();
});
}
}
20 changes: 2 additions & 18 deletions src/Notifications/Alliances/Discord/AllianceCapitalChanged.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@
namespace Seat\Notifications\Notifications\Alliances\Discord;

use Seat\Eveapi\Models\Alliances\Alliance;
use Seat\Eveapi\Models\Character\CharacterNotification;
use Seat\Eveapi\Models\Sde\SolarSystem;
use Seat\Notifications\Notifications\AbstractNotification;
use Seat\Notifications\Jobs\AbstractCharacterNotification;
use Seat\Notifications\Services\Discord\Messages\DiscordEmbed;
use Seat\Notifications\Services\Discord\Messages\DiscordEmbedField;
use Seat\Notifications\Services\Discord\Messages\DiscordMessage;
Expand All @@ -36,25 +35,10 @@
*
* @package Seat\Notifications\Notifications\Alliances\Discord
*/
class AllianceCapitalChanged extends AbstractNotification
class AllianceCapitalChanged extends AbstractCharacterNotification
{
use NotificationTools;

/**
* @var \Seat\Eveapi\Models\Character\CharacterNotification
*/
private $notification;

/**
* AllianceCapitalChanged constructor.
*
* @param \Seat\Eveapi\Models\Character\CharacterNotification $notification
*/
public function __construct(CharacterNotification $notification)
{
$this->notification = $notification;
}

/**
* @param $notifiable
*
Expand Down
20 changes: 2 additions & 18 deletions src/Notifications/Alliances/Slack/AllianceCapitalChanged.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,35 +24,19 @@

use Illuminate\Notifications\Messages\SlackMessage;
use Seat\Eveapi\Models\Alliances\Alliance;
use Seat\Eveapi\Models\Character\CharacterNotification;
use Seat\Eveapi\Models\Sde\MapDenormalize;
use Seat\Notifications\Notifications\AbstractNotification;
use Seat\Notifications\Jobs\AbstractCharacterNotification;
use Seat\Notifications\Traits\NotificationTools;

/***
* Class AllianceCapitalChanged.
*
* @package Seat\Notifications\Notifications\Alliances\Slack
*/
class AllianceCapitalChanged extends AbstractNotification
class AllianceCapitalChanged extends AbstractCharacterNotification
{
use NotificationTools;

/**
* @var \Seat\Eveapi\Models\Character\CharacterNotification
*/
private $notification;

/**
* AllianceCapitalChanged constructor.
*
* @param \Seat\Eveapi\Models\Character\CharacterNotification $notification
*/
public function __construct(CharacterNotification $notification)
{
$this->notification = $notification;
}

/**
* @param $notifiable
* @return array
Expand Down
98 changes: 98 additions & 0 deletions src/Notifications/Characters/Discord/Killmail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

/*
* This file is part of SeAT
*
* Copyright (C) 2015 to 2020 Leon Jacobs
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

namespace Seat\Notifications\Notifications\Characters\Discord;

use Seat\Eveapi\Models\Corporation\CorporationInfo;
use Seat\Eveapi\Models\Killmails\KillmailDetail;
use Seat\Notifications\Jobs\AbstractNotification;
use Seat\Notifications\Services\Discord\Messages\DiscordEmbed;
use Seat\Notifications\Services\Discord\Messages\DiscordEmbedField;
use Seat\Notifications\Services\Discord\Messages\DiscordMessage;
use Seat\Notifications\Traits\NotificationTools;

/**
* Class Killmail
*
* @package Seat\Notifications\Notifications\Characters\Discord
*/
class Killmail extends AbstractNotification
{
use NotificationTools;

/**
* @var \Seat\Eveapi\Models\Killmails\KillmailDetail
*/
private $killmail;

/**
* Killmail constructor.
*
* @param \Seat\Eveapi\Models\Killmails\KillmailDetail $killmail
*/
public function __construct(KillmailDetail $killmail)
{
$this->killmail = $killmail;
}

/**
* @inheritDoc
*/
public function via($notifiable)
{
return ['discord'];
}

/**
* @param $notifiable
*
* @return \Seat\Notifications\Services\Discord\Messages\DiscordMessage
*/
public function toDiscord($notifiable)
{
return (new DiscordMessage())
->content('A kill has been recorded for your corporation!')
->embed(function (DiscordEmbed $embed) {
$embed->timestamp($this->killmail->killmail_time);
$embed->author('SeAT Kilometer', asset('web/img/favico/apple-icon-180x180.png'));

$embed->field('Ship Type', $this->killmail->victim->ship->typeName);
$embed->field('zKB Link', sprintf('https://zkillboard.com/kill/%d/', $this->killmail->killmail_id));
$embed->field(function (DiscordEmbedField $field) {
$field->name('System');
$field->value(
$this->zKillBoardToDiscordLink(
'system',
$this->killmail->solar_system_id,
sprintf('%s (%s)',
$this->killmail->solar_system->name,
number_format($this->killmail->solar_system->security, 2))));
});

$embed->thumb($this->typeIconUrl($this->killmail->victim->ship_type_id));
$embed->footer('zKillboard', 'https://zkillboard.com/img/wreck.png');

(CorporationInfo::find($this->killmail->victim->corporation_id)) ?
$embed->color(DiscordMessage::ERROR) : $embed->color(DiscordMessage::SUCCESS);
});
}
}
81 changes: 81 additions & 0 deletions src/Notifications/Characters/Discord/NewMailMessage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

/*
* This file is part of SeAT
*
* Copyright (C) 2015 to 2020 Leon Jacobs
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

namespace Seat\Notifications\Notifications\Characters\Discord;

use Illuminate\Support\Str;
use Seat\Notifications\Jobs\AbstractNotification;
use Seat\Notifications\Services\Discord\Messages\DiscordEmbed;
use Seat\Notifications\Services\Discord\Messages\DiscordMessage;

/**
* Class NewMailMessage
*
* @package Seat\Notifications\Notifications\Characters\Discord
*/
class NewMailMessage extends AbstractNotification
{
/**
* @var
*/
private $message;

/**
* NewMailMessage constructor.
*
* @param $message
*/
public function __construct($message)
{
$this->message = $message;
}

/**
* @inheritDoc
*/
public function via($notifiable)
{
return ['discord'];
}

/**
* @param $notifiable
*
* @return \Seat\Notifications\Services\Discord\Messages\DiscordMessage
*/
public function toDiscord($notifiable)
{
return (new DiscordMessage())
->content('New EVEMail Received!')
->embed(function (DiscordEmbed $embed) {
$embed->timestamp($this->message->timestamp);
$embed->author('SeAT Personal Agent', asset('web/img/favico/apple-icon-180x180.png'));

$embed->description(Str::limit(
str_replace('<br>', ' ', clean_ccp_html($this->message->body->body, '<br>')),
2000));

$embed->field('Subject', $this->message->subject);
$embed->field('Sent Date', $this->message->timestamp);
});
}
}
2 changes: 1 addition & 1 deletion src/Notifications/Characters/Mail/Killmail.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

use Illuminate\Notifications\Messages\MailMessage;
use Seat\Eveapi\Models\Killmails\KillmailDetail;
use Seat\Notifications\Notifications\AbstractNotification;
use Seat\Notifications\Jobs\AbstractNotification;
use Seat\Notifications\Traits\NotificationTools;

/**
Expand Down
Loading

0 comments on commit d0d810b

Please sign in to comment.