I was wondering what happens to everything in the withdraw thread? In this picture, both deposit and withdraw are affecting the balance object. I just want to make sure of something,is the stuff on the right stored and if so, when/how does it then appear again. I also want to make sure my vocab is correct... in this case am I creating a race condition?
image
What is shown in your picture is the "execution sequence" of the operations. So assume you only have one CPU, the CPU first executes two operations from the Deposit thread, switch to the Withdraw thread and execute 4 operations, then switch back to the Deposit thread and execute two more operations.
So this is the answer to your question in the picture "Is all this part gone forever and never used?": At the time represented by the blank area you point to, the Withdraw thread is just idle (or terminated).
Related
For example, a program that sends a token or nft to a specific address once a month.
No program on solana will be executed unless an off-chain actor submits a transaction containing an instruction for that program. There is no timer mechanism inherent to solana that will automatically execute your transactions at a later date.
You can write a program to restrict an instruction such that it can only be executed successfully once per month. The program can check the current timestamp against a previous execution to check if it's allowed to execute now. Or it could check the number of months since the previous execution and transfer the appropriate number of tokens that should be available after that number of months.
Additionally, you need to consider the incentives of the actor who submits the instruction. Does an ordinary user have reason to execute some instructions in your program already? If it fits within the compute budget, you can bundle this monthly logic along with the other logic that users routinely execute. If not, then you need to incentivize someone else to make sure the instruction is executed often enough. You could just submit a transaction once a month on your own. Or you could design your program to collect fees from ordinary users so it can pay rewards to a crank turner who runs these periodic instructions so you don't have to. You also need to let people know they can get paid for running a crank.
So, there are ways to get things to run periodically, but you need to get creative to make it happen. There are some interesting ideas that build on the primitives I have described, you can go pretty far down this rabbit hole. It has been proposed that multisig can play a role in a generic cron timer. As always, this would still require someone to turn the crank by submitting transactions to the network periodically. https://github.com/solana-labs/solana/issues/17218
I'm trying to model the following: When filling out a submission form, the system automatically saves the users progress every 5 minutes.
This is what I tried, but I don't think it's correct.
In my case the condition is asked only after the "fill submission" activity is finished. Also I don't want to indicate, that the user is starting the "fill submission" activity again.
You would use an interruptible region represented by a dashed line box:
The timer interrupt appears independently and intrerrupts the current action. Auto save is executed and comes back with Fill form. Resuming Fill form need a bit of thought since usually you have some entry code which must not be executed in case of a continuation. That might be a bit more tricky as you would likely need a mutex for that.
UML 2.5 has a detailed description in chap. 15.6.3.2 Interruptible Activity Regions on pp. 405.
Just a word about your approach. The save is only executed when the form is closed. So if it takes longer than 5 minutes you end up in your form again which is likely not desired :-)
I am trying to figure out how to handle consistency in the database.
In scenario:
User A has an accounting document in the database include a balance field representing the amount of his current money. (supposed initially he has 100$)
My system has many methods to charge his account.
Suppose 2 methods occur at the same time, each method charges him for 10$, these steps occur concurrently in below orders:
Method 1 READ his balance and store in memory (100$)
Method 2 READ his balance and store in memory (100$)
... some business logics
Method 1 UPDATE his balance by subtracting variable in memory by 10 (100$ - 10$) and then save it
Method 2 UPDATE his balance by subtracting variable in memory by 10 (100$ - 10$) and then save it
This means he has been charged only 10$ instead of 20$.
I searched this situation a while and can not get it clear (sorry for my stupidity).
Really appreciate yours helps to enlighten my featherbrained. :)
You just discovered why financial transactions are complicated :-)
Have you ever wondered why it takes time for you to have an updated balance in your bank account? Or why you actually have two balances, instead of one?
That's because your account can actually go negative and (up to a certain point) that will be fine.
So in a real life scenario what happens is that you have a balance of 100$, you pay 10$ and until that transaction is processed and confirmed by the receiver, you still have your 100$. If you do 20 transactions of 10$ each, you'll be able to complete them because the system will most likely not be able to notice.
And honestly, it shouldn't. Think of credit cards, you might not have enough money now, but maybe you know you'll have enough when the credit is due.
So, the race condition you describe only works if you actually read the value and then update it.
There are a few approaches:
Read the current balance, and update the row using the old balance as a field in the where statement. This way if it updates no rows you know that you need to re-read and update.
Don't update the balance and only do it time-based, say once per hour. Yes, you might still have to do some checks, but the system will overall be more responsive.
Lock the database row as your first step. This would work but there's a chance that it will make the app slower.
Race condition you describe is low level design concern. With backend engine like Node that will handle the incomming request in first come first serve fashion you don't need to think about this case. Race condition you describe is not possible if you respect the order in which database update callbacks are fired. They are fired in the same order they have been issued in. So you should call next update only when the previous has finished. Promisses are great way to do this.
I want to see the intrinsic difference between a thread and a long-running go block in Clojure. In particular, I want to figure out which one I should use in my context.
I understand if one creates a go-block, then it is managed to run in a so-called thread-pool, the default size is 8. But thread will create a new thread.
In my case, there is an input stream that takes values from somewhere and the value is taken as an input. Some calculations are performed and the result is inserted into a result channel. In short, we have input and out put channel, and the calculation is done in the loop. So as to achieve concurrency, I have two choices, either use a go-block or use thread.
I wonder what is the intrinsic difference between these two. (We may assume there is no I/O during the calculations.) The sample code looks like the following:
(go-loop []
(when-let [input (<! input-stream)]
... ; calculations here
(>! result-chan result))
(recur))
(thread
(loop []
(when-let [input (<!! input-stream)]
... ; calculations here
(put! result-chan result))
(recur)))
I realize the number of threads that can be run simultaneously is exactly the number of CPU cores. Then in this case, is go-block and thread showing no differences if I am creating more than 8 thread or go-blocks?
I might want to simulate the differences in performance in my own laptop, but the production environment is quite different from the simulated one. I could draw no conclusions.
By the way, the calculation is not so heavy. If the inputs are not so large, 8,000 loops can be run in 1 second.
Another consideration is whether go-block vs thread will have an impact on GC performance.
There's a few things to note here.
Firstly, the thread pool that threads are created on via clojure.core.async/thread is what is known as a cached thread pool, meaning although it will re-use recently used threads inside that pool, it's essentially unbounded. Which of course means it could potentially hog a lot of system resources if left unchecked.
But given that what you're doing inside each asynchronous process is very lightweight, threads to me seem a little overkill. Of course, it's also important to take into account the quantity of items you expect to hit the input stream, if this number is large you could potentially overwhelm core.async's thread pool for go macros, potentially to the point where we're waiting for a thread to become available.
You also didn't mention preciously where you're getting the input values from, are the inputs some fixed data-set that remains constant at the start of the program, or are inputs continuously feed into the input stream from some source over time?
If it's the former then I would suggest you lean more towards transducers and I would argue that a CSP model isn't a good fit for your problem since you aren't modelling communication between separate components in your program, rather you're just processing data in parallel.
If it's the latter then I presume you have some other process that's listening to the result channel and doing something important with those results, in which case I would say your usage of go-blocks is perfectly acceptable.
Im new to threads, therefore im not sure if threads are the right way to approach this.
My program needs to perform a calculation a couple of times, same logik behind it, but with different parameters. The longer the calculation, the closer it will be to the perfect answer. The calculation duration cant be measured beforehanded (from a few seconds to a couple of minutes)
The user wants to have the results in an order (from calculation 1 to X) at certain times. He is satisfied with not the perfect solution as long as it he gets a result. Once he has a solution, he is not interested in the one before (example: he has a not perfect answer from calculation 1 and demands now answer from calculation 2; even if there is a better answer now for calculation 1, he is not interested in it)
Is threading the right way to do this?
Threading sounds like a good approach for this, as you can perform your long-running computation on a background thread while keeping your UI responsive.
In order to satisfy your requirement of having results in an order, you may need a way of stopping threads that are no longer needed. Either abort them (may be extreme), or just signal them to stop and/or return the current result.
Note you may want the threads to periodically check back in with the UI to report progress (% complete), check for any abort requests, etc. Although this depends entirely upon your application and is not necessarily required.