Hyperledger transaction react to another event/transaction - hyperledger

Is there a standard way to have a transaction listen for events or other transactions and when fulfilled conditions occur (ie: a specific event happens), to run the transaction code.
Ie: Sell house only when money is received, receiving money is a different transaction.
Or does one simply Poll, set an alarm with an external service that is listening on the channel for events? Is there a standard approach here?

if a transaction updates a PropertyListing asset (using its ID) to PAYMENT_RECEIVED (eg. the seller's solicitor has received the monies for the property transaction held in escrow etc so, as a party submits the transaction to indicate so), then the house asset can automatically be updated to 'SOLD' and post an event that your Client App listens for.
Your client application can then initiate the next step in the process, eg the agreement to transfer the title etc (however that is done in your use case, may be another transaction to show 'acceptance' manual or automatic as you wish). I say 'client app' because I assume there is a level of user interaction to sign it off as a means of agreement
See more on events here and subscribing to events here

Related

Broadcast to only one web socket in room using ActionCable

I am using ActionCable to provide Browser Notification which is easy to implement. The problem is coming when a user has open the multiple tabs in the browser and I need to send the data to only one tab i.e to only one WebSocket in user room. How can this be done?
Isolating a single pub/sub client isn't directly possible with the pub/sub approach, because the whole idea is that publishers have no knowledge of subscribers.
However, there are two common ways to solve this:
to use a different named channel per connection, saving the named channel in the database and forwarding all messages to that specific named channel (i.e. saving the channel user-ID-TIMESTAMP in the database and using it as the target connection).
another, somewhat more reliable approach (though more complex) is to send the message to all clients but create a race condition that allows only a single client to receive the actual message. This would look something like this:
server sends "you have a message" to all clients.
client polls "undelivered" messages from the server.
server locks the message pool or uses a database transaction in order to retrieve undelivered messages and mark the messages as delivered. The server sends the undelivered messages to the client (optionally setting an ACK timeout).
a single client connection receives the undelivered messages the rest get an empty array of messages (since they were all delivered to the other client) or receive a "delivered" flag so the data is updated but no notification is raised.
(optional) the client sends and ACK.
(optional) the server marks the message delivery as complete. If no ACK was received before "timeout", server unmarks delivery and resends the "you have a message" message.
Good luck!
Every time a new connection is made we will create a new room. So for example when the user is making a new connection we can give the room name as users:user_id:some_unique_random_string which may be equal to users:user_id:123j123b1h2b1j23bh12b3 and when the same user makes another connection by opening another tab we will also do the same and create a separate room.
Now one thing the ActionCable provides is that we can find all the room name followed by any prefix.
Lets the user has made three connections and their rooms are users:128:123n1jh123ko9876, users:128:asdas23412cs1234, users:128:asni9202h5i3jens then we can obtain these room name using ActionCable also.
user_id = 128
pubsub = ActionCable.server.pubsub
channel_with_prefix = pubsub.send(:channel_with_prefix, RoomChannel.channel_name)
channels = pubsub.send(:redis_connection).pubsub('channels', "#{channel_with_prefix}:users:#{user_id}:*")
Now the channels is an array consisting of the rooms name.
So puts channels
["chatapp_production:users:128:123n1jh123ko9876", "chatapp_production:users:128:asdas23412cs1234", "users:128:asni9202h5i3jens"]
This is how we can find all the rooms related to a single user without using any external database and API calls.

Ensure that communication between iOS application and back-end succeeded

Simple question: How to ensure that a communication between an iOS application and a back-end succeeded?
Detail: For most of the API call in our mobile application, it can be "OK" if the communication between the application and the server fails (for network reason or other), we can just display a message to the user with a retry button to reload his news or posts feed for instance.
However, on some occasion, we want to be really confident that the communication between the application and the backend will never fail and the data of this communication will potentially be "lost".
For this, let's take as an example, the In-App Purchases (IAP):
In my app, an IAP information looks like this:
struct InAppPurchase{
// The id of the purchase
let transactionId: String
// The id of the user who purchased
let userId: String
// The IAP product involved in the purchase (10 or 30 in-app coins for example)
let productId: String
}
Everytime a user makes a purchase, I want to send this information to the back-end in order to save a history of the purchases made in my application.
I don't want to miss any of those communications between the application and the server (if a user send me a feedback saying that he paid for some item in my app I want to make sure by checking the history that he really made the purchase)
If the purchase succeeds but the call to send the information to the server fail (Network error or else), this information can't be lost and must be sent as soon as possible.
I was thinking of this approach:
Creating a pending purchase array with UserDefault or Keychain like so
var pendingPurchases = [InAppPurchase]()
When the user purchases an item, this item is store in the pendingPurchases array.
The application communicates with the back-end by sending this array of IAP
If I receive the answer code 200 SUCCESS from the back-end, I can purge the pendingPurchases array.
If I receive another code for an ERROR, I try to send this call another time (limited to 3 in a row, if it is because of bad network, it maybe not needed to try sending the request indefinitely at the moment) until receiving 200 SUCCESS
Each time the application is open or switch from background to foreground, I check if the pendingPurchases is empty or not. If not empty, I send the request to the server.
What do you think of this approach? How do you manage this kind of data that you don't want to be "lost"?
What you want to do is wait to "finish the transaction" until you've received a 200 response from your server. If you don't finish the transaction, Apple will save it in a payment queue and keep sending it to you every time the app launches. This will give you an opportunity to handle any retries to your server if needed.
Finishing a transaction tells StoreKit that you’ve completed
everything needed for the purchase. Unfinished transactions remain in
the queue until they’re finished, and the transaction queue observer
is called every time your app is launched so your app can finish the
transactions. Your app needs to finish every transaction, regardless
of whether the transaction succeeded or failed.
Complete all of the following actions before you finish the
transaction:
Persist the purchase.
Download associated content.
Update your app’s UI to let the user access the product.
To finish a transaction, call the finishTransaction: method on the payment queue.
SKPaymentTransaction *transaction = <# The current payment #>;
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
You can read more about finishing transactions in Apple's doc below:
https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/DeliverProduct.html

iOS iap restore process on multiple devices - SKReceiptRefreshRequest or restoreCompletedTransactions etc

I know there is a lot of info but I sill can't decide what is the proper way of restoring IAP subscriptions between devices. Obviously, after digging the net, there is no really good documentation about this and people have to deal with it mainly by trials and errors.
I'm on the point to finalyze my first app with IAP subscriptions and have some doubts before I'm ready to upload it for approval. It seems like the behaviour during testing is quite different than the production one and I just don't have the production experience yet to be sure what is going on exactly.
The way I have implemented the process is the following:
The user purchase the item for first time so he/she makes a payment and the transaction is added to the queue.
When the app receives the response it calls finishTransaction and validates the receipt (it can be local or remote but it's a different question)
When the renewal comes the queue notifies the app and the app again calls finishTransaction and makes a new validation.
This works fine on one device and there are no problems.
However when I want to restore those purchases on another device the renewal notification might not be sent as the first device that receives the notification calls finishTransaction and all other devices just miss it.
Then I have two options - either to refresh the receipt by using SKReceiptRefreshRequest or restoring the purchases by using restoreCompletedTransactions. I make one of these at a certain time based on the previous purchase expiration date just to check if the user didn't stop the subscription. (Subscription cancelation is another topic - similar but for now I don't mind it)
The refresh process looks like the one I prefer but, at least in Sandbox, it always asks the user to log in (twice and I don't know if it's normal, plus that in sandbox I couldn't find a way to implement the Touch ID). Then the app receives a new refreshed receipt and goes through the validation process which is great.
The second method requests silently a new receipt (which is a plus over the previous) but as far as I can understand it always doubles the amount of transactions in the new receipt as it make a new transaction for every completed one:
The payment queue will deliver a new transaction for each previously
completed transaction that can be restored. Each transaction includes
a copy of the original transaction.
So... my questions are:
Is the production behaviour the same like the sandbox for the SKReceiptRefreshRequest - should the user sign in every time the app wants to refresh the receipt and does integrating Touch ID requires some other implementation?
If I have, let's say Week Subscriptions, it would be quite annoying to the user.
If I use restoreCompletedTransactions will the receipt at some point becomes full of useless transactions?
If the user had, again let's say one year of Week Subscriptions and restores them on a few other devices, they all will fill up the final receipt quite a lot.
Overall which method is preferable and what are the Pros and Cons for each of them.
Thanks a lot!

Microservices out of sync

Application architecture has three microservices; let's call them A, B, and C.
A is the authority for holding user permissions (including permissions for sending SMS) and when permissions update it publishes an Event for services interested in this data.
B and C listen for permissions changes, to control sending SMS.
Main Rails App is integrating with A, B, C.
App updated A with permissions to prevent student A from receiving any SMS,
and then A published the event which gets delayed in Queueworker;
App started to send SMS through B, which is not updated yet because of Queueworker delay.
How can we ensure (or what is need to be changed in design to ensure) users will not receive SMS once permissions changed to false?
You're running into the biggest challenge of distributed systems -- the CAP theorem. To summarize, a distributed system (like you have) can never guarantee all three of the below:
Consistency - all services see the same data at the same time
Availability - all services' requests to each other receive a success or failure response
Partition tolerance - the system continues to function even when services cannot reach each other
In your specific problem, the lack of consistency is hurting you. You can fix it, but you'll have to give up one of the other points. For example, before sending each SMS, you could have service B perform a synchronous HTTP request to service A to verify that the intended recipient still has permissions to receive SMSes. This will fix your consistency issue, but creates a dependency that A must be up and running for B to function (meaning, you've lost the P from CAP).
You could also mitigate the issue by sending SMS requests as events through the same queue that the permission updates go through. It's still possible for an SMS to send after the permission was disabled, but that would only happen if the permission update came in after the SMS was meant to be sent. This is still lacking consistency, but the impact is less severe (at a cost of SMS latency).

Suggtestions for sending e-mail notifications from a 2 tier application with client potentially not connected to the internet

I have to add e-mail notifications to a client server application.
Notifications happen as the user do some particular action on the client UI.
If I had a middle tier or a service running at server I can imagine how to do it:
1) I simply create a DB tables with "pending notifications"
2) as a user does an action that generates a notification I add a record to the table
3) serverside I would continuously try to send those mails and removing them from the table once sending is succesful
Now I cannot do this now, I have a plan to add a service later on, but for now I must go the quick and dirty way.
So somehow what I was thinking to is to implement something like this:
1) as a notify-worth event occurs at client, the same client (my exe) tries to send the notification, upon failure it will log the notification in the "pending notifications" table (failure can be becuase lack of internet connection or any other problem)
2) I add a Timer that will work from any client machine to check for pending notifications. If there are any the client will try to send the e-mail (using a transaction: I will mark a field as "TryngToSendFromClientX" and in case of failure I will reset that field to NULL)
I think this approach would work, it has obvious limitations (if after failure no one logs into the system, no notification will be sent - same would be if service goes "down"). But can you comment on this approach and suggest a better one?
Additional notes (to better understand the scenario):
a) Note: all notifications are sent from the same e-mail account.
b) I don't need to keep track of who sent the e-mail.
c) the problem of creating the service now is that it will basically complicate significantly deployment and I need to create tools for monitoring the status of the service. Something that I will do in future but not now, in future I have plan to add more functionality (not only sending notifications) to the service, so in that case it makes more sense to create it.
d) I will send e-mails by using Indy components and SMTP server.
If you are not willing to create the service now, I think you are stuck with the scenario you describe. There are some things though you could do to circumvent the problem of no user firing up the client anymore while there are still pending messages.
You could add a commandline utility (or commandline parameter as bepe4711 suggested) that will only check for pending messages and try to send them.
Add this commandline utility to the StartUp folder or Run key in the registry. This way messages will at least get sent when the computer restarts, even if the user does not fire up the your app.
Add a scheduled task to run this utility at least once every day. The scheduled task can be added by code or by your installer.
If you do both, you will only have to worry about pending messages of users that never start their computer again.
Perhaps you can add a parameter to your client which causes it to just look at the pending notifications and send them. After this it can terminate itself. It will just act like some kind of service.
Then you install the client on the server and start it every x minutes.
I do something very similar to the approach you describe. Instead of sending emails I need to call a web service. My application is installed on several laptops and they are commonly not connected to any network.
When my application raises an exception I collect various bits of information including user comments and screen shots. Then I attempt to send this to our web service. If by chance the web service is not available. (i.e. not connected to the internet or web service is down) I write the results to an XML file on disk in the User Profile (App_Data) directory.
The one major difference is I don't poll to check to see if the server is up. I attempt to send them again on the startup of the application.
If both Systems are running on Windows, have a look at MS Message Queue. It is designed to send notifications to systems, which are not allways online. I did it in .Net, there are already easy to use classes implemented. Not sure about Delphi.
Latest version of Windows uses much more the Windows Task Scheduler, and now task can be fired on event (i.e. when a network card gets connected...). You could write a separate utility that tries to send pending notification, even if noone is logged in.

Resources