I am building a scalable chat application using Go and Redis w/ websockets.
I need to publish a new message using redis pub-sub model to other websocket servers to inform all the users (saved in memory of other servers) about the new joined user.
But the issue is, the publisher(also a redis client) receives the same message. Is there a direct way to solve this?
Workaround:
Check if the user for new user in the received event (for publisher) is in the list of current local users everytime.
WHY NEGATIVE VOTES? I'm so pissed at stack-overflow these days. People have no tolerance or too much arrogance
So I know that compared to most more decentralized blockchains that Solana is fast.
Still, the question I have is whether I should implement my transactions asynchronously off of a queue - so that I can retry failures if something fails etc
This gets further complicated for example if I am using metaplex to create a token with associated metadata etc as it involves 2 transactions: 1 to create the token and another to create the token-metadata for the token
You're absolutely encouraged to retry transactions as appropriate. Here is an excerpt from the Solana Cookbook which gives the TLDR for retrying:
RPC nodes will attempt to rebroadcast transactions using a generic algorithm
Application developers can implement their own custom rebroadcasting logic
Developers should take advantage of the maxRetries parameter on the sendTransaction JSON-RPC method
Developers should enable preflight checks to raise errors before transactions are submitted
Before re-signing any transaction, it is very important to ensure that the initial transaction’s blockhash has expired
You can read the full source at https://solanacookbook.com/guides/retrying-transactions.html
I currently manage an integration into Opayo Direct (v4.00). We send requests to Opayo, which most of the time work fine, but occasionally they time out (Our timeout limit is currently set to 20s, which is ages for a consumer to wait).
Does anyone know of a way to either:
Retry the payment request without double charging the consumer? or,
Send a follow up request to get the status of the submitted payment?
For 2. it looks like you need valid transaction identifier from Opayo, which of course we won't have as the request has timed out.
I can't see any mention of idempotency or guidance for what to do in this situation, even in their most recent API specification (PI integration).
Has anyone come up with a workable solution for this problem, other than change provider?
I am using Spring Boot and not much experience on Transactions stuff...
#Service
#Transactional
class FundTransferService {
public void doSomeFunds(){
if(realPaymentGateway()){
//then do db call, to update User Transaction details, WHAT IF SERVER GOES DOWN HERE OR ANY EXCEPTION??
}
}
public boolean realPaymentGateway(){
//Using Braintree to transfer Funds
}
}
Above there are 2 things happening, paymentGateway(which is some rest call) and if success, then only updating DB with User Transaction details.
I want above 2 THINGS should happen Atomic, I mean either both (Rest and DB) shud Success, or rollback everything..
My problem is:
Q1) While Updating DB details, due to some exception or server goes down, then might rollback happen only for DB stuff, but not RESTCALL..
Q2) Should I first update DB and then go for PaymentGateway for transfering funds or reverse should be correct? Please suggest me..
Hope you understand my query, so whats the solution for above problem?
You cannot atomically do what you want to do, like span a distributed transaction, because Braintree is a REST service outside of your control.
You can however, call Braintree, and afterwards update your database accordingly. This way, there's a minimal time-window right between your brain-tree call and your transaction commit, that your server gets unexpectedly "killed", but there's no easy way around that in the scope of this answer.
You could also have some sort of write-ahead-log, where you try and remember what REST service you are going to call and then reconcile with the actual REST calls that happened, but this is a bit more elaborate and quite possibly overkill.
You can apply transactions only for transactional resources. As I understood you have 1 non-transactional input (further, TX) (call with payment request) and 2 outputs (non-TX remote REST call and TX SQL database). If you want to keep real-time consistency, I can propose the next architectural approach:
- put payment request into message queue. MQ Broker must support XA protocol for 2PC commit (for instance, ActiveMQ);
- your service reads message from queue using XA-connection, sends REST request to remote server and saves data into DB (which also supports XA protocol) using XA-connection;
- if REST call will failed or something else, you will rollback changes and start from processing payment request from the queue again. BTW, your remote REST resource must be idempotent;
If you're using non-transactional resoureces no way to keep it in consistent .
Also, you can lookup information, for instance, on Atomikos site for using 2PC.
Trying to create a true bi-directional websocket server using akka http & akka-stream
Server will answer a request when the response in ready
Server will answer a request with multiple responses when those are ready
Server will push a notification without being asked anything
The official https://doc.akka.io/docs/akka-http/current/server-side/websocket-support.html#handling-messages is not really clear.
Creating the Route for the server
public Route createRoute() {
return path("subscription", () ->
get(() ->
concat(
handleWebSocketMessages(subscriptionFlow()))));
}
public Flow<Message, Message, NotUsed> subscriptionFlow() {
I find that you need to return the Flow that would handle the in/out messages.
Thinking that there is no request/response for the messages but just a weak link I will need a separate Sink for the requests and a separate Source for sending responses although the Sink still needs to know about the Source so it can later know to whom does this answer is sent to.
I have only found examples of request/response or the Sink is completely ignored and maybe one older example https://markatta.com/codemonkey/posts/chat-with-akka-http-websockets-old/
I am thinking to use Flow.fromSinkAndSourceCoupled and maybe a have an actor that is created for every websocket connection
I cannot get to work the idea of Sink.actorRefWithBackpressure, Source.actorRefWithBackpressure, Flow.fromSinkAndSourceCoupled and creating the actor for every websocket connection.
On the typed Actor (currently 2.6.3) I cannot find a way to create the actor for every websocket connection just like in the old example
val userActor = system.actorOf(Props(new User(chatRoom)))
Is there an example on akka / akka-stream / akka-http projects, or somewhere that shows this feature ?