Not All Messages Forwarded to SQS from GetStream.io - amazon-sqs

Setup: A flat feed (representing an artist) is followed by another flat feed (representing users). Activities are added to the artist feed and the expectation is that those activities show on the feeds of all users following an artist and are then forwarded to a queue in AWS SQS.
Problem: The problem is that not all messages are appearing in SQS. We have extensive logging in place and never see some messages show either in the queue or lambda which consumes the queue. This functionality was working last week (2020-04-22) without any code changes in the meantime.
Debugging Notes:
Activities show in the artist and user feeds in the GetStream.io dashboard but not SQS
"Test SQS" button in GetStream.io dashboard generates a success message and the test message is visible in the queue and consuming lambda
Some messages are forwarded to SQS while others are not
Decoded sample message that did get through to SQS:
{'new': [{'actor': '30026dd3-c557-46a0-b1c3-20b6e2dc5e2d', 'foreign_id': 'social_spike_twitter:GlobalParticipant_30026dd3-c557-46a0-b1c3-20b6e2dc5e2d', 'id': '37114000-7f75-11ea-8080-8000273a69c4', 'object': '{"new_followers":100}', 'origin': 'participant_spike:GlobalParticipant_30026dd3-c557-46a0-b1c3-20b6e2dc5e2d', 'target': '', 'time': '2020-04-16T00:00:00.000000', 'verb': 'social_spike_twitter'}], 'deleted': [], 'deleted_foreign_ids': [], 'feed': 'user_mobile_push:ArtistProfile_19', 'app_id': 39400, 'published_at': '2020-04-22T18:11:58.160Z'}

Related

SQS Event Bridge Once Per Minute

We are looking at Event Bridge to give us a scheduled task added to our SQS once per minute.
We are looking at Event Bridge to make it happen. So far it properly puts messages into the queue, but we are trying to schedule it for once per minute and noticing that the queue only gets messages once per five minutes sometimes six minutes.
The metrics seem to state invocation is happening; however, the queue isn't receiving them in the time frame specified.
Considerations
SQS FIFO Queue - Deduplication
Constant JSON String
The "duh" of not seeing messages at prescribed interval is because of this in the AWS documentation:
The token used for deduplication of sent messages. If a message with a
particular message deduplication ID is sent successfully, any messages
sent with the same message deduplication ID are accepted successfully
but aren’t delivered during the 5-minute deduplication interval
Open to suggestions and will be looking for a workaround.
Update
I tried using Input Transformer to fix by adding the time as uniquely changing item in the queue message; however, still not getting below 5 minutes.
Variable Input
{"addedOn":"$.time"}
Message
{"AddedOn":<addedOn>}
The queue polling built into SQS just wasn't polling for my updated count of greater than 10 messages. Once I deleted out the old messages the timing was correct and it was updating 1/min.
The answer is if you are going to use a constant string it'll have to be for scheduled jobs that are greater than 5 minutes.
Adding info here despite redundancy from question for linked Google searches:
The token used for deduplication of sent messages. If a message with a particular message deduplication ID is sent successfully, any messages sent with the same message deduplication ID are accepted successfully but aren’t delivered during the 5-minute deduplication interval
Despite the messages being a unique event once per minute the Constant (JSON text) not being unique still saw it as a duplicate to remove.
To solve I switched to Input transformer
Example event and what you other fields you can add as variables:
{
"version": "0",
"id": "7bf73129-1428-4cd3-a780-95db273d1602",
"detail-type": "EC2 Instance State-change Notification",
"source": "aws.ec2",
"account": "123456789012",
"time": "2015-11-11T21:29:54Z",
"region": "us-east-1",
"resources": [
"arn:aws:ec2:us-east-1:123456789012:instance/i-abcd1111"
],
"detail": {
"instance-id": "i-0123456789",
"state": "RUNNING"
}
}
I needed a unique variable so time was an obvious choice.
Input for Input Transformer
Input Path:
{"addedOn":"$.time"}
Template:
{"AddedOn":<addedOn>}
Documentation
Also, found that moving over to not using FIFO queues is a potential solution if that's an easy option for future SQS developers as well.

Twilio Target Worker Expression--blocking voice calls while on a text

I've read the documentation here: https://www.twilio.com/docs/taskrouter/multitasking#preventing-a-worker-from-receiving-chat-tasks-if-on-a-voice-task on how to block an agent from getting chats while they are on a voice call, but I want to do the reverse with a twist.
I successfully managed to stop workers from getting a voice call while they have an active chat going using "worker.channel.chat.assigned_tasks == 0" as the Expression. However, it also prevents a second chat, SMS, Facebook, or WhatsApp message coming in even though the worker's capacity is higher than 1.
Would love suggestions on what the expression should be so that the additional SMS or chats can come through up to the worker's capacity but not any voice calls when they have an active chat or SMS going.
The following filter should do the trick. The expression will only apply to voice tasks and the target routes to workers with no assigned chats.
{
"filter_friendly_name": "Do not assign Voice Tasks if assigned Chat",
"expression": "(task_channel_unique_name=='voice')",
"targets": [
{
"queue": <default queue sid>,
"expression": "worker.channel.chat.assigned_tasks == 0"
}
]
},

Calendar ID in create response differs from what Graph stores

We are experiencing inconsistencies with calendar ID's.
When sending a POST to https://graph.mircrosoft.com/v1.0/me/calendars with the following payload
{ name: 'Calendar' }
We receive this reponse from which we store the id
{
:"#odata.context"=>"https://graph.microsoft.com/v1.0/$metadata#users('user%40outlook.com')/calendars/$entity",
:id=>"AQMkADAwATMwMAItMjE5ZC01YjYyLTAwAi0wMAoARgAAA1D6u4KwtRdMm1rAZoOEKvAHAMf0BP7S_89KmnrxCgze9tcAAAIBBgAAAMf0BP7S_89KmnrxCgze9tcAAAEBKdoAAAA=",
:name=>"Calendar",
:color=>"auto",
:changeKey=>"x/QE/tL7z0qaevEKDN721wAAAAAOFQ==",
:canShare=>true,
:canViewPrivateItems=>true,
:canEdit=>true,
:owner=>{:name=>"User", :address=>"user#outlook.com"}
}
When we attempt to create events into this calendar errors are being thrown as that ID does not exist. Looking into it further and making a GET request to https://graph.mircrosoft.com/v1.0/me/calendars we receive this payload (truncated for brevity)
{
:id=>"AQMkADAwATMwMAItMjE5ZC01YjYyLTAwAi0wMAoARgAAA1D6u4KwtRdMm1rAZoOEKvAHAMf0BP7S_89KmnrxCgze9tcAAAIBBgAAAMf0BP7S_89KmnrxCgze9tcAAAIjxAAAAA==",
:name=>"Calendar",
:color=>"auto",
:changeKey=>"I8E7t/aNjEqDHtJJL1UC6AAADFI=",
:canShare=>true,
:canViewPrivateItems=>true,
:canEdit=>true,
:owner=>{:name=>"User", :address=>"user#outlook.com"}}]
}
After diffing both ID's, we notice they differ. The interesting part of this is that this only happens with a handful of users and isn't an issue with most accounts. Is there a better way to keep track of specific calendars that we can continue to sync into? I'd hate to have to ping for calendars every time we'd like to fire off a CRUD action.

Does Firebase always guarantee added events in order?

I am developing messenger IOS app based on Firebase Realtime Database.
I want that all messages to be ordered based on timestamp.
There is a scenario as like below.
There are 3 clients. A, B and C.
1)
All clients register 'figure-1' listener to receive messages from others.
<figure-1>
ref.queryOrdered(byChild: "timestamp").queryStarting(atValue: startTime).observe(.childAdded, with:
{
....
// do work for the messages, print, save to storage, etc.
....
// save startTime to storage for next open.
startTime = max(timeOfSnapshot, startTime)
saveToStorage(startTime)
}
2)
Client A write message 1 to server with ServerValue.timestamp().
Client B write message 2 to server with ServerValue.timestamp().
Client C write message 3 to server with ServerValue.timestamp().
They sent messages extremely the same moment.
All clients have good speed wifi.
So, finally. Server data saved like 'figure-2'
<figure-2>
text : "Message 1", timestamp : 100000001
text : "Message 2", timestamp : 100000002
text : "Message 3", timestamp : 100000003
As my listener's code, i keep messages on storage and next listening timestamp for preventing downloading duplicated messages.
In this case.
Does Firebase always guarantee to trigger callback in order as like below?
Message 1
Message 2
Message 3
If it is not guaranteed, my strategy is absolutely wrong.
For example, some client received messages as like below.
Message 3 // the highest timestamp.
// app crash or out of storage
Message 1
Message 2
The client do not have chance to get message 1, 2 anymore.
I think if there are some nodes already, Firebase might trigger in order for those. Because, that is role of 'queryOrdered' functionality.
However, there are no node before register the listener and added new nodes additionally after then. What is will happen?
I suppose Firebase might send 3 packets to clients. (No matter how quickly the message arrives, Firebase has to send it out as soon as it arrives.)
Packet1 for message1
Packet2 for message2
Packet3 for message3
ClientA fail to receive for packet 1,2
ClientA success to receive for packet 3
Firebase re-send packet 1,2 again.
ClientA success to receive for packet 1,2
Eventually, all datas are consistent. But ordering is corrupted.
Does Firebase guarantee to occur events in order?
I have searched stack overflow and google and read official documents many times. However, i could not find the clear answer.
I have almost spent one week for this. Please give me piece of advice.
The order in which the data for a query is returns is consistent, and determined by the server. So all clients are guaranteed to get the results in the same order.
For new data that is sent to the database after the listeners are attached, all remote clients will receive it in the same order. The local client will see events for it's write operation right away though, before the data even reaches the database server.
In figure 2, it is actually quite simple: since each node has a unique timestamp, and they will be returned in the order of that timestamp. But even if they'd have the same timestamp, they'd be returned in the same order (timestamp first, then key) for each client.

Twilio SWIFT API get consumed messages always returns 0

I want to display next to a chat channel the number of messages a channel has that have been unconsumed or unread (I assume this is what unconsumed means?)
Currently I send messages to a channel that two users are subscribed to , a private chat. Then before opening up the chat window I check the channel for unconsumed messages, but it always say 0 messages even if I call setNoMessagesConsumedWithCompletion.
I am using the Swift API...What do I need to do to find out how many messages in my channel have not been read yet? At what point do they become read? (when the user opens up a chat channel and requests to getLastWithCount?)
I read in the docs you have to set something called the consumption horizon to get unconsumed message, but I don't know how you do that in SWIFT API https://www.twilio.com/docs/chat/consumption-horizon also this was for Javascript API so perhaps it is easier with Swift Api?
I figured out the solution. As per the documentation you need to update the last consumed message index. So for example if the user has a chat window open you need to record for that user (or instance of the Chat Client) what was the last message they saw before they close their chat. I am storing all the messages in a message array and update the last consumed message index with the length of the array of messages:
generalChannel?.messages?.setLastConsumedMessageIndex(NSNumber.init(value: self.messages.count), completion: { (result, count) in
if !result.isSuccessful() {
print(result.error.debugDescription)
}
})
Then if you send messages to that channel when the user is not in the channel these will be recorded as unconsumed, you can get the number by calling:
channel.getUnconsumedMessagesCount(completion: { (results, numberUnconsumed) in
print(numberUnconsumed)
})

Resources