I am using activemq to send messages. Due to the number of messages being sent and the amount of other work the application is sending. I've enabled async sending.
When the application ends I want to be sure the remaining messages are actually delivered as we sometimes miss one of the last messages that go on the connection.
Googling around I found only the warnings that state you might miss some messages well this is acceptable however we miss some of the last ones about 40% of the time. I wish to improve this situation.
Q: Is there any method to check wether the activemq producer/sender has sent all it's async messages?
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory( brokerUrl );
connectionFactory.setUseAsyncSend( true );
RedeliveryPolicy policy = connectionFactory.getRedeliveryPolicy();
policy.setInitialRedeliveryDelay( 500 );
policy.setBackOffMultiplier((short)2);
policy.setUseExponentialBackOff(true);
policy.setMaximumRedeliveries(10);
You could set the async send mode back to off for the last message which would cause the client to wait on the send until the broker acknowledges that the message has been received. The Connection object would need to be cast to ActiveMQConnection and then you can call setUseAsyncSend(false)
Related
Working on an Android app to send data to a peripheral device via BLE. Question about Android BluetoothGATTCallback onCharacteristicWrite function - how does it know that the write transaction was successful? Is success assumed so long as no error occurs? Or does it record a success response of some sort sent from the peripheral device characteristic to which data is written?
I would say matdev's comments in his answer is not correct, at least according to my experience.
Assuming you use "Write With Response" (WRITE_TYPE_DEFAULT) rather than "Write Without Response" (WRITE_TYPE_NO_RESPONSE), the following applies:
First you call writeCharacteristic. This method performs some sanity checks, such as the characteristic you are trying to write to has the "write" property, there are no other pending GATT operations on this BluetoothGatt object, and that the object is not closed. If those sanity checks are passed, this method returns true.
The write request is then transferred over the air to the remote device's GATT server. Here the request is processed and the GATT server returns a Write Response or an Error Response with an error code, which is sent back to the Android device. When Android receives a Write Response, it will call onCharacteristicWrite with GATT_SUCCESS (0) as status. If Android instead receives an Error Response, it will call onCharacteristicWrite and set the status to the code included in the Error Response. If the GATT server e.g. returns 0x80 (Application Error) or 0x13 (Value Not Allowed), this is the status code you will receive in your callback.
If the connection drops before the response is received, Android will call the callback with some currently undocumented non-success status code.
If you instead use "Write Without Response" (WRITE_TYPE_NO_RESPONSE), the behaviour of onCharacteristicWrite changes. Now, this callback is instead used for flow control. When the local Bluetooth stack's buffers are ready to accept another packet, this is when you will get the callback. This can happen even before the packet is sent over the air.
You can assume the BLE write transaction is successful if the status param of BluetoothGATTCallback's onCharacteristicWrite() equals BluetoothGatt.GATT_SUCCESS i.e. 0
If an error occurs, the status value will indicate the type of error, such as
/** GATT write operation is not permitted */
public static final int GATT_WRITE_NOT_PERMITTED = 0x3;
Here is an extract of the doc about onCharacteristicWrite():
Params:
...
status – The result of the write operation BluetoothGatt.GATT_SUCCESS if the operation succeeds.
I have a very simple application for sending bulk messages.
It sends a single message to 20 groups.
The delay that I declare between send messages is "8".
It means about 7~8 send message request per minute.
The documentation says "telegram api has a limit of 20 request per minute".
It means I am using less than half of the limit.
But still, I am getting lots of flood wait errors.
And those wait errors has like 84.000second wait limit.
I am facing 2 errors while getting floodwait error.
1-
Security error while unpacking a recevied message: Server replied with a wrong session ID
2-
Floodwaiterror invoked while sending a message; forcing 70792 second wait interval for ....
I really don't know why this is happening.
The number I am trying to send message is brand new. Clear. Unbanned. Unspammed.
As I said wait interval between 2 messages is 8 seconds, means less than the limits for a minute.
Sessions are correct because it sends couple message but after couple it gets instantly tons of floodwaiterrors from 0 to 70k.
Could you help me to understand what is causing that please?
I have the same problem and solution is to pass the entity object instead of string name of receiver party.
was:
results = await client.send_message("mybot", message="hello")
now:
with TelegramClientSync(StringSession(session_id), api_id, api_hash) as client:
bot_entity = client.get_input_entity(peer="mybot")
results = await client.send_message(entity=bot_entity, message=message)
We are building a real-time chat app using Firestore. We need to handle a situation when Internet connection is absent. Basic message sending code looks like this
let newMsgRef = database.document(“/users/\(userId)/messages/\(docId)“)
newMsgRef.setData(payload) { err in
if let error = err {
// handle error
} else {
// handle OK
}
}
When device is connected, everything is working OK. When device is not connected, the callback is not called, and we don't get the error status.
When device goes back online, the record appears in the database and callback triggers, however this solution is not acceptable for us, because in the meantime application could have been terminated and then we will never get the callback and be able to set the status of the message as sent.
We thought that disabling offline persistence (which is on by default) would make it trigger the failure callback immediately, but unexpectedly - it does not.
We also tried to add a timeout after which the send operation would be considered failed, but there is no way to cancel message delivery when the device is back online, as Firestore uses its queue, and that causes more confusion because message is delivered on receiver’s side, while I can’t handle that on sender’s side.
If we could decrease the timeout - it could be a good solution - we would quickly get a success/failure state, but Firebase doesn’t provide such a setting.
A built-in offline cache could be another option, I could treat all writes as successful and rely on Firestore sync mechanism, but if the application was terminated during the offline, message is not delivered.
Ultimately we need a consistent feedback mechanism which would trigger a callback, or provide a way to monitor the message in the queue etc. - so we know for sure that the message has or has not been sent, and when that happened.
The completion callbacks for Firestore are only called when the data has been written (or rejected) on the server. There is no callback for when there is no network connection, as this is considered a normal condition for the Firestore SDK.
Your best option is to detect whether there is a network connection in another way, and then update your UI accordingly. Some relevant search results:
Check for internet connection with Swift
How to check for an active Internet connection on iOS or macOS?
Check for internet connection availability in Swift
As an alternatively, you can check use Firestore's built-in metadata to determine whether messages have been delivered. As shown in the documentation on events for local changes:
Retrieved documents have a metadata.hasPendingWrites property that indicates whether the document has local changes that haven't been written to the backend yet. You can use this property to determine the source of events received by your snapshot listener:
db.collection("cities").document("SF")
.addSnapshotListener { documentSnapshot, error in
guard let document = documentSnapshot else {
print("Error fetching document: \(error!)")
return
}
let source = document.metadata.hasPendingWrites ? "Local" : "Server"
print("\(source) data: \(document.data() ?? [:])")
}
With this you can also show the message correctly in the UI
I have a server-side streaming gRPC service that may have messages coming in very rapidly. A nice to have client feature would be to know there are more updates already queued by the time this onNext execution is ready to display in the UI, as I would simply display the next one instead.
StreamObserver< Info > streamObserver = new StreamObserver< info >( )
{
#Override
public void onNext( Info info )
{
doStuffForALittleWhile();
if( !someHasNextFunction() )
render();
}
}
Is there some has next function or method of detection I'm unaware of?
There's no API to determine if additional messages have been received, but not yet delivered to the application.
The client-side stub API (e.g., StreamObserver) is implemented using the more advanced ClientCall/ClientCall.Listener API. It does not provide any received-but-not-delivered hint.
Internally, gRPC processes messages lazily. gRPC waits until the application is ready for more messages (typically by returning from StreamObserver.onNext()) to try to decode another message. If it decodes another message then it will immediately begin delivering that message.
One way would be to have a small, buffer with messages from onNext. That would let you should the current message, and then check to see if another has arrived in the mean time.
I want to implement a chat system.
I am stuck at the point where user sends multiple messgaes really fast. Although all the messages are reached to the server but in any order.
So I thought of implementing a queue where each message shall
First be placed in queue
Wait for its turn
Make the post request on its turn
Wait for around 5 secs for the response from server
If the response arrives within time frame and the status is OK, message sent else message sending failed.
In any case of point 5, the message shall be dequeued and next message shall be given chance.
Now, the major problem is, there could be multiple queues for each chat head or the user we are talking to. How will I implement this? I am really new to dart and flutter. Please help. Thanks!
It sounds like you are describing a Stream - a series of asynchronous events which are ordered.
https://www.dartlang.org/guides/language/language-tour#handling-streams
https://www.dartlang.org/guides/libraries/library-tour#stream
Create a StreamController, and add messages to it as they come in:
var controller = StreamController<String>();
// whenever you have a message
controller.add(message);
Listen on that stream and upload the messages:
await for(var messsage in controller.messages) {
await uploadMessage(message);
}