[heketi-devel] To pass a *bolt.DB or a *bolt.Tx

Raghavendra Talur rtalur at redhat.com
Thu Mar 9 22:03:34 UTC 2017


On Fri, Mar 10, 2017 at 3:21 AM, Michael Adam <obnox at samba.org> wrote:
> Hi Talur,
>
> Thanks for this write-up!
>
> It sounds all very consistent.
>
> But I will want to thoroughly look at the code.
> The Mutex thing sounds a bit like complete
> serialization (for write processes).

Yes, for small functions, this would completely serialize the
goroutines and essentially we lose all the benefits. I could not come
up with any better solution though.


>
> Cheers - Michael
>
> On 2017-03-10 at 02:03 +0530, Raghavendra Talur wrote:
>> Here is what Bolt documentation says about transactions:
>>
>> ```
>> Transactions
>>
>> Bolt allows only one read-write transaction at a time but allows as
>> many read-only transactions as you want at a time. Each transaction
>> has a consistent view of the data as it existed when the transaction
>> started.
>>
>> Individual transactions and all objects created from them (e.g.
>> buckets, keys) are not thread safe. To work with data in multiple
>> goroutines you must start a transaction for each one or use locking to
>> ensure only one goroutine accesses a transaction at a time. Creating
>> transaction from the DB is thread safe.
>> ```
>>
>> Now, in heketi, there some operations at app.* level that might have
>> to view/update many buckets(node,brick,volumes,device). The methods of
>> these objects take either a *bolt.Tx or a *bolt.DB.
>>
>> In my understanding, there are some app.* operations where it is a
>> must that all the methods that are called within it, should get the
>> same view of db; in that case, it makes sense that app.* function
>> starts a tx and hands it down to the lower methods thereby ensuring a
>> consistent view.
>>
>> Some methods however, like Create and Destroy methods of brick have
>> been written to take a *bolt.DB as a argument. This seems to be done
>> to enable use of goroutines. Now, we have functions in the higher
>> layer calling these very methods which would want the operation to be
>> done in the transaction created above.
>>
>> In PR #710 I have made two changes to tackle the above problem:
>> 1. Changed these methods to take *bolt.Tx as arg instead of *bolt.DB
>> 2. Introduce a sync.Mutex  as another member of StatusGroup, any
>> goroutines that want to operate on the db using a shared tx must call
>> the new Lock() method of StatusGroup and call Unlock() after the db
>> operation is done.
>>
>> In summary, as bolt documentation suggests, to work with data in
>> multiple go routines:
>> we used to: start a transaction for each one
>> now we do: mutex locking to ensure only one goroutine accesses a
>> transaction at a time
>>
>> If there are better ideas, they are most welcome.
>>
>> Thanks,
>> Raghavendra Talur
>> _______________________________________________
>> heketi-devel mailing list
>> heketi-devel at gluster.org
>> http://lists.gluster.org/mailman/listinfo/heketi-devel


More information about the heketi-devel mailing list