4 ms·
I'm all for finding ways to avoid locking and using immutable objects is one way to help, but this: Remove the mutation part and now you have a version histo
by hvs 15y ago
I'm all for finding ways to avoid locking and using immutable objects is one way to help, but this:
Remove the mutation part and now you have a version history,
allowing conflict resolution.
is a little too "hand-wavy" for my tastes. Conflict resolution is not an easier problem than resource contention.
- hashbo 15y agoFair point, maybe I should have been clearer (and an edit will be forthcoming). My point is that with a version history it’s possible to let the content originator know there is a conflict and allow them to choose which version they wish to go with. This can be as simple as diplaying an icon to show there has been a conflict and giving the choice to keep or revert, showing the other users changes, like most wikis. Or much more complex like in a version control system. My point is more the negative here, you can’t do conflict resolution if you write over the previous state. Sorry if it was hand wavy, was just a quick Friday afternoon blog :-)
- hvs 15y agoFair enough. I'm on your side about keeping a version history and using immutable data (for some things). Its just that my biggest question when I was reading (as it is any time someone discusses concurrency) is: how does he handle updates to the "same" data? Because, ultimately, you will have state somewhere in your system.
- hashbo 15y agoSo the simple answer is that right now we use a most recent wins strategy because our data is not critical or highly correlated like relational data. For us it’s simple to add at a future date UI features to allow wiki style history. Obviously with correlated data it’s not so easy :-) and that is, as I believe you were implying, where versioning gets tricky! Of course point still applies about the need to avoid mutation :-)
- wccrawford 15y agoI agree. Locking is used because the code needs to make sure nothing else modifies that data while it's reading it. If you don't lock, and the data is modified, the program could crash. Adding version history to it doesn't change this fact. Example: You're iterating over bank records, marking them paid. Another thread adds one to the beginning of the list. Thread 1 finishes marking them paid, then moves them all to the 'paid' section... Including the non-paid one.
- hashbo 15y agoActually copy on write would help you 100% here :-) you just need to take the abstraction a level up. That is mutations to your list would create a new list. The original thread continues reading the stale copy. Therefore reducing consistency issues. You will see that is how (in Java) ConcurrentHashMap works for example. There’s no magic bullet ever in coding, but CoW can make life a lot easier, and certainly that is my experience. So I’m just encouraging folk to think about adding it to their toolkit. Thanks for the comments though it’s interesting to talk about the use cases.
- wccrawford 15y agoActually, no it wouldn't. The second thread makes a copy of the list and adds a new item. The next time the first thread goes through to mark everything 'paid', it either gets an empty list, or a list that still contains everything it supposedly moved elsewhere earlier, depending on how you handle it.
- ori_b 15y agoRight, you need lazy lists (or generators) for this to work naturally. eg, in python: paid = (markpaid(x) for x in list_records())