mail icon indicating copy to clipboard operation
mail copied to clipboard

FallbackMailer: shuffle mailers with given probability

Open JanTvrdik opened this issue 8 years ago • 11 comments

  • bug fix? no
  • new feature? yes
  • BC break? no
  • doc PR: would be nice to have

Intended to periodically test the other mailers. I'm not sure whether default $shuffleProbability should be 0.0 or sth like 0.001 (would be a minor BC break).

JanTvrdik avatar Apr 10 '17 12:04 JanTvrdik

@janedbal Can you elaborate?

JanTvrdik avatar Apr 10 '17 13:04 JanTvrdik

@JanTvrdik I don't like the intention. If you want to periodically test other mailers, include it in your CI or cron task. IMHO fallback mailer should be used in "emergency" cases, then you can for example track usage of the fallback mailer to measure reliability of your primary mailer.

janedbal avatar Apr 10 '17 13:04 janedbal

@janedbal Production SMTP servers are rarely tested on CI (because CI does not have access to production credentials). Also being able to send mail from CI does not mean you will be able to send mail from production (different firewall configuration…).

Reliability can be tracked via onFailure event. The default probability is zero, meaning nothing changes unless you explicitly asked for random shuffling to be enabled (although this is up for discussion).

JanTvrdik avatar Apr 10 '17 13:04 JanTvrdik

Well, adding such functionality into a constructor isn't good. It also violates SRP. Introducing a "ShuffleMailer" may be the right way.

hrach avatar Apr 10 '17 13:04 hrach

Introducing a "ShuffleMailer" may be the right way.

Feel a lot like overengineering. This is three lines of code. Creating new class would just make this a lot harder to use.

BTW: FallbackMailer intentionally already violates SRP (the „correct“ approach would be to split it to RetryingMailer and FallbackMailer).

JanTvrdik avatar Apr 10 '17 13:04 JanTvrdik

It also violates SRP. Introducing a "ShuffleMailer" may be the right way.

💯

Majkl578 avatar Apr 10 '17 13:04 Majkl578

Feel a lot like overengineering.

Agreed. Maybe the question is if a such unique functionality should be included in the framework.

BTW: FallbackMailer intentionally already violates SRP

This argument is based on the actual implementation, but the general intention is in your case totally different - the current Fallback mailer tries to send the mail in any case, tries to solve some failures and outages. Your extension actually doesn't increase such possibility of successfull send at all, but it introduces possibility to test the infrastructure. That's another usecase, therefore the logic should be IMO separated.

hrach avatar Apr 10 '17 14:04 hrach

Intended to periodically test the other mailers.

This clearly doesn't sound like something that should be done in production. If your mailers are unreliable, you should test them in different manner, i.e. by your monitoring, not by randomly using them in production (or rather not use them in production at all)...

FallbackMailer should probably be renamed to FallbackRetryingAndWaitingAndTestingByShufflingMailer.

Seriously, shuffling of the mailers has absolutely no relation to fallback mailing. Also it's just a rare use case imho (which you can easily implement in user-land).

Majkl578 avatar Apr 10 '17 15:04 Majkl578

This clearly doesn't sound like something that should be done in production

I disagree, imho production is the only place this can be accurately done from. Yes, you can use monitoring to test whether the mail servers are running, but that does not mean that the application will be able to actually send mails.

FallbackMailer should probably be renamed to FallbackRetryingAndWaitingAndTestingByShufflingMailer

Maybe MoreReliableMailer would be better name as all those 3 responsibilities are intended to increase reliability of mail delivery, but FallbackMailer looks good enough to me.

JanTvrdik avatar Apr 24 '17 11:04 JanTvrdik

Because it instantly modifies the input argument and because it is tricky (or hard to explain, reuse, whatever), I think it can be better solved in the config:

mail.mailer: Nette\Mail\FailbackMailer(MyTools::suffleMailers([@onemailer, @secondmailer]))
function MyTools::suffleMailers(array $mailers, $shuffleProbability = 0.01)
{
   if ($shuffleProbability > 0.0 && mt_rand() / mt_getrandmax() < $shuffleProbability) {
		shuffle($mailers);
   }
   return $mailers;
}

dg avatar Apr 24 '17 12:04 dg

Because it instantly modifies the input argument

We can move the actual shuffle to send() + decrease the probability to zero to avoid shuffling for each send() call.

JanTvrdik avatar Apr 24 '17 12:04 JanTvrdik