I deleted a queue by accident in Amazon SQS. Is there a way to retrieve/undo the delete?
No, the queue (and any messages on the queue) are gone forever.
If you recreate the queue with the same name, it will keep the same ARN and URL. Hopefully you've got the configuration documented :-)
Related
We have a Worker which had a bug that caused eroneous responses to a method being called. The issue has since been fixed, however when we restart the background workers we seem to still experience the issue.
We know the issue is resolved because for the meantime we have moved the logic to a rake task and it is now working fine. We suspect the issue relates to failed or unperformed jobs in the sidekiq queue.
We tried to overcome this by clearing the redis DB with the below approach:
Sidekiq.redis { |r| puts r.flushall }
Has anyone experienced a similar issue when using Sidekiq/Redis and how did you over come it?
I think flushall might just retry immediately all the still failed, but still queued, jobs
In most cases, if you fix a bug in the worker without changing the signature, you may be able to just let them retry (assuming the job itself is idempotent which is kinda recommended for this reason and others).
If however, the bug was in what you were passing into the async job call, then you'll have to remove all those entries because they will continue to fail every time they are retried which, by default, can go on for weeks.
I think what you want to do is clear them all... you can do it for that particular queue. You may have to be careful to not remove jobs that are newly queued if that's a problem by perhaps examining the job entries. If you just want to nuke them all:
queue = Sidekiq::Queue.new('your_queue')
queue.clear
When a task is successfully created it is supposed to be added to the queue of the thing that created that task. But what are the possible reasons that a task is not appearing in the queue?
I guess you are not creating queueitem record or somehow your existing automation is broken. That’s why task record is not showing up in queue.
Queue is a container to keep all the activities/records in track, but the actual activity/record will not be associated in Queue but the Queue Item record.
Make sure to create a queueitem record for your task & set it to the right queue.
Read more
I want to create SQS using code whenever it is required to send messages and delete it after all messages are consumed.
I just wanted to know if there is some delay required between creating an SQS using Java code and then sending messages to it.
Thanks.
Virendra Agarwal
You'll have to try it and make observations. SQS is a dostributed system, so there is a possibility that a queue might not immediately be usable, though I did not find a direct documentation reference for this.
Note the following:
If you delete a queue, you must wait at least 60 seconds before creating a queue with the same name.
https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_CreateQueue.html
This means your names will always need to be different, but it also implies something about the internals of SQS -- deleting a queue is not an instantaneous process. The same might be true of creation, though that is not necessarily the case.
Also, there is no way to know with absolute certainty that a queue is truly empty. A long poll that returns no messages is a strong indication that there are no messages remaining, as long as there are also no messages in flight (consumed but not deleted -- these will return to visibility if the consumer resets their visibility or improperly handles an exception and does not explicitly reset their visibility before the visibility timeout expires).
However, GetQueueAttributes does not provide a fail-safe way of assuring a queue is truly empty, because many of the counter attributes are the approximate number of messages (visible, in-flight, etc.). Again, this is related to the distributed architecture of SQS. Certain rare, internal failures could potentially cause messages to be stranded internally, only to appear later. The significance of this depends on the importance of the messages and the life cycle of the queue, and the risks of any such an issue seem -- to me -- increased when a queue does not have an indefinite lifetime (i.e. when the plan for a queue is to delete it when it is "empty"). This is not to imply that SQS is unreliable, only to make the point that any and all systems do eventually behave unexpectedly, however rare or unlikely.
I was wondering if there was a best practice for notifying the end of an sqs queue. I am spawning a bunch of generic workers to consume data from a queue and I want to notify them that they can stop processing once they detect no more messages in the queue. Does sqs provide this type of feature?
By looking at the right_aws ruby gem source code for SQS I found that there is the ApproximateNumberOfMessages attribute on a queue. Which you can request using a standard API call.
You can find more information including examples here:
http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/APIReference/Query_QueryGetQueueAttributes.html
For more information on how to do this using the right_aws gem in ruby look at:
https://github.com/rightscale/right_aws/blob/master/lib/sqs/right_sqs_gen2_interface.rb#L187
https://github.com/rightscale/right_aws/blob/master/lib/sqs/right_sqs_gen2_interface.rb#L389
Do you mean "is there a way for the producer to notify consumers that it has finished sending messages?" . If so, then no there isn't. If a consumer calls "ReceiveMessage" and gets nothing back, or "ApproximateNumberOfMessages" returns zero, that's not a guarantee that no more messages will be sent or even that there are no messages in flight. And the producer can't send any kind of "end of stream" message because only one consumer will receive it, and it might arrive out of order. Even if you used a separate notification mechanism such as an SNS topic to notify all consumers, there's no guarantee that the SNS notification won't arrive before all the messages have been delivered.
But if you just want your pool of workers to back off when there are no messages left in the queue, then consider setting the "ReceiveMessageWaitTimeSeconds" property on your queue to its maximum value of 20 seconds. When there are no more messages to process, a ReceiveMessage call will block for up to 20s to see if a message arrives instead of returning immediately.
You could have whatever's managing your thread pool query ApproximateNumberOfMessages to regularly scale/up down your thread pool if you're concerned about releasing resources. If you do, then beware that the number you get back is Approximate, and you should always assume there may be one or more messages left on the queue even if ApproximateNumberOfMessages returns zero.
I'm using a Observer on my classes. When one of the records is created/updated I need to notfify another service (via a URL call). What is the best way to do this to avoid slowing down my class? Would using a gem liked delayed_job be overkill?
In my Observer's after_update() / after_create() I just want to launch a thread that calls the URL...
If your notifier is non-thread blocking, you could simply spawn a thread and perform the notification there. That way, your program will continue to run while that thread is waiting on the response.
Of course, you'll want some way to handle failure. You could have it try three times, and if it still fails, write a notification to the log or something.
The best (most reliable) solution would be to use a job queue. That way, if a job fails outright, you can inspect and resubmit the job again.
Definitely use a community supported/accepted gem like delayed_job or resque. It's really not as hard as you think and your app will scale better down the line.