# Problema con sidekiq

**URL:** <https://www.ruby-forum.com/t/problema-con-sidekiq/228306>\
**Category:** IT\
**Created:** [April 17, 2013, 11:58am UTC](https://www.ruby-forum.com/t/problema-con-sidekiq/228306 "2013-04-17T11:58:13Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![fregini](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/a88e4f/32.png) [@fregini](https://www.ruby-forum.com/u/fregini)\
**Post date:** [April 17, 2013, 11:58am UTC](https://www.ruby-forum.com/t/problema-con-sidekiq/228306/1 "2013-04-17T11:58:13Z")

</div>

L’ho posato sulla lista di sidekiq, lo posto pure qua magari c’  
qualcuno che, per non lo traduco, scusate!

–

I have a worker which sends an email then writes to database. To avoid  
to send the same email twice, as a safety measure, I generate a SHA from  
email address + body.

Code looks like this, more or less:

```
 if EmailDigest.find_by_hash_id(composer.hash_id)
   Rails.logger.warn("Skipping email delivery for 

```

#{composer.hash\_id}")  
else  
DigestMailer.digest(composer).deliver  
EmailDigest.create!(hash\_id: composer.hash\_id)  
end

The problem is that I received a few exceptions on create! line, because  
hash\_id was already taken, which is what the first line should check  
for.

So I’m assuming there’s some concurrency issue, but the only thing I can  
think of is two sidekiq worker working on the same queued item.  
Or a worker working on the same item again. Is there any way to make  
this happen? Any advice to give?

–

In pratica come se il primo controllo venisse bypassato. Boh.  
Grattacapo.

-f

---

<div class="post-metadata">

**Author:** ![fregini](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/a88e4f/32.png) [@fregini](https://www.ruby-forum.com/u/fregini)\
**Post date:** [April 17, 2013, 12:36pm UTC](https://www.ruby-forum.com/t/problema-con-sidekiq/228306/2 "2013-04-17T12:36:12Z")

</div>

Hai provato ad usare find\_or\_create\_by?  
In generale sidekiq ha di questi problemi proprio perche’ e’ multithread  
e volendo anche multiprocesso.

Se cerchi nel wiki del progetto ti fa capire che casi del genere possono  
capitare tranquillamente, l’importante  
e’ che i worker siano idempotenti in modo tale che possono essere  
eseguiti anche diverse volte (anche  
dando errore) senza realmente provocare alcun danno.

Ti consiglio di dare un’occhiata qui:

> **[Best Practices](https://github.com/sidekiq/sidekiq/wiki/Best-Practices)**
>
> Simple, efficient background processing for Ruby. Contribute to sidekiq/sidekiq development by creating an account on GitHub.

Se proprio invece vuoi processare con certi limiti (anche se credo sia  
sconsigliato da sidekiq stesso),  
puoi usare: [GitHub - deanpcmad/sidekiq-limit\_fetch: A Sidekiq plugin to support advanced queue control (limiting, pausing, blocking, querying)](https://github.com/brainopia/sidekiq-limit_fetch)

Ciao

–  
Matteo L.

> **[The eCommerce consultancy for category disruptors | Nebulab](https://nebulab.com/)**
>
> We are the full-service eCommerce agency behind some of the world’s most innovative digital brands. Let's talk about your project.

Il giorno 17/apr/2013, alle ore 11:57, Fabrizio R.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) ha scritto:

---

<div class="post-metadata">

**Author:** ![fregini](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/a88e4f/32.png) [@fregini](https://www.ruby-forum.com/u/fregini)\
**Post date:** [April 17, 2013, 1:11pm UTC](https://www.ruby-forum.com/t/problema-con-sidekiq/228306/3 "2013-04-17T13:11:15Z")

</div>

Avevo letto le best practices, per questo ho impostato quel controllo di  
sicurezza. Ma sinceramente pensavo si trattasse di edge cases non di  
normale operativit. Ho cominciato a lavorarci da poco ed errori del  
genere accadono molto di frequente.

-f

---

<div class="post-metadata">

**Author:** ![fregini](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/a88e4f/32.png) [@fregini](https://www.ruby-forum.com/u/fregini)\
**Post date:** [April 17, 2013, 4:03pm UTC](https://www.ruby-forum.com/t/problema-con-sidekiq/228306/4 "2013-04-17T16:03:39Z")

</div>

Grazie. Per il momento ho optato per una scelta diversa.  
Essenzialmente ho eliminato il controllo preventivo, e mi affido alla  
exception potenziale del database per decidere se spedire l’email. Non  
perfetto perch l’invio dell’email pu sempre fallire dopo che ho  
salvato il record nel database.  
Poi mi rinfresco la memoria con il tutorial che mi hai mandato. Ed  
eventualmente rifattorizzo tutto dopo che capito bene come padroneggiare  
la Forza.

-f

---

<div class="post-metadata">

**Author:** ![fregini](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/a88e4f/32.png) [@fregini](https://www.ruby-forum.com/u/fregini)\
**Post date:** [April 17, 2013, 2:07pm UTC](https://www.ruby-forum.com/t/problema-con-sidekiq/228306/5 "2013-04-17T14:07:22Z")

</div>

2013/4/17 Fabrizio R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> ```
> EmailDigest.create!(hash_id: composer.hash_id)
> end
> 
> ```
> 
> The problem is that I received a few exceptions on create! line, because  
> hash\_id was already taken, which is what the first line should check for.
> 
> So I’m assuming there’s some concurrency issue, but the only thing I can  
> think of is two sidekiq worker working on the same queued item.  
> Or a worker working on the same item again. Is there any way to make this  
> happen? Any advice to give?

> In pratica come se il primo controllo venisse bypassato. Boh. Grattacapo

🙂

Benvenuto nella programmazione multithread.

[http://www.tutorialspoint.com/ruby/ruby\_multithreading.htm](http://www.tutorialspoint.com/ruby/ruby_multithreading.htm)

Prova cos:

require ‘thread’  
mutex = Mutex.new

```
if EmailDigest.find_by_hash_id(**composer.hash_id)
   Rails.logger.warn("Skipping email delivery for 

```

#{composer.hash\_id}")  
else  
mutex.synchronize do  
if not EmailDigest.find\_by\_hash\_id(\*\*composer.hash\_id)  
DigestMailer.digest(composer).\*\*deliver  
EmailDigest.create!(hash\_id: composer.hash\_id)  
end  
end  
end

Certo che il multithreaded programming … che noia.

Non c’ un modo pi elegante ?  
😉

S.
