Currently ConstraintProcessor latches onto prePut() to perform validation
check.

>From HRegion.doMiniBatchPut() where prePut() is called:
    /* Run coprocessor pre hook outside of locks to avoid deadlock */
So to make use of Constraint in Suraj's scenario, we have some decisions to
make about various factors.

Cheers

On Sun, Dec 4, 2011 at 8:39 AM, Suraj Varma <svarma...@gmail.com> wrote:

> Jesse:
> >> Quick soln - write a CP to check the single row (blocking the put).
>
> Yeah - given that I want this to be atomically done, I'm wondering if
> this would even work (because, I believe I'd need to unlock the row so
> that the checkAndMutate can take the lock - so, there is a brief
> window between where there is no lock being held - and some other
> thread could take that lock). One option would be to pass in a lock to
> checkAndMutate ... but that would increase the locking period and may
> have performance implications, I think.
>
> I see a lot of potential in the Constraints implementation - it would
> really open up CAS operations to do functional constraint checking,
> rather than just value comparisons.
>
> --Suraj
>
> On Sun, Dec 4, 2011 at 8:32 AM, Suraj Varma <svarma...@gmail.com> wrote:
> > Thanks - I see that the lock is taken internal to checkAndMutate.
> >
> > I'm wondering whether it is a better idea to actually pass in a
> > Constraint (or even Constraints) as the checkAndMutate argument. Right
> > now it is taking in an Comparator and a CompareOp for verification.
> > But, this could just be a special case of Constraint which is
> > evaluated within the lock.
> >
> > In other words, we could open up a richer Constraint checking api
> > where any "functional" Constraint check can be performed in the
> > checkAndPut operation.
> >
> > This would also not have the same performance impact of taking a
> > rowLock in preCheckAndPut and release in postCheckAndPut. And - it is
> > really (in my mind) implementing the compare-and-set more generically.
> >
> > I also see the potential of passing in multiple constraints (say
> > upper/lower bounds in Increment/Decrement operations) etc.
> >
> > --Suraj
> >
> >
> > On Sat, Dec 3, 2011 at 7:44 PM, Ted Yu <yuzhih...@gmail.com> wrote:
> >> From HRegionServer.checkAndPut():
> >>    if (region.getCoprocessorHost() != null) {
> >>      Boolean result = region.getCoprocessorHost()
> >>        .preCheckAndPut(row, family, qualifier, CompareOp.EQUAL,
> comparator,
> >>          put);
> >> ...
> >>    boolean result = checkAndMutate(regionName, row, family, qualifier,
> >>      CompareOp.EQUAL, new BinaryComparator(value), put,
> >>      lock);
> >> We can see that the lock isn't taken for preCheckAndPut().
> >>
> >> To satisfy Suraj's requirement, I think a slight change to
> checkAndPut() is
> >> needed so that atomicity can be achieved across preCheckAndPut() and
> >> checkAndMutate().
> >>
> >> Cheers
> >>
> >> On Sat, Dec 3, 2011 at 4:54 PM, Suraj Varma <svarma...@gmail.com>
> wrote:
> >>
> >>> Just so my question is clear ... everything I'm suggesting is in the
> >>> context of a single row (not cross row / table). - so, yes, I'm
> >>> guessing obtaining a RowLock on the region side during preCheckAndPut
> >>> / postCheckAndPut would certainly work. Which was why I was asking
> >>> whether the pre/postCheckAndPut obtains the row lock or whether the
> >>> row lock is only obtained within checkAndPut.
> >>>
> >>> Let's say the coprocessor takes a rowlock in preCheckAndPut ... will
> >>> that even work? i.e. can the same rowlock be inherited by the
> >>> checkAndPut api within that thread's context? Or will preCheckAndPut
> >>> have to release the lock so that checkAndPut can take it (which won't
> >>> work for my case, as it has to be atomic between the preCheck and
> >>> Put.)
> >>>
> >>> Thanks for pointing me to the Constraints functionality - I'll take a
> >>> look at whether it could potentially work.
> >>> --Suraj
> >>>
> >>> On Sat, Dec 3, 2011 at 10:25 AM, Jesse Yates <jesse.k.ya...@gmail.com>
> >>> wrote:
> >>> > I think the feature you are looking for is a Constraint. Currently
> they
> >>> are
> >>> > being added to 0.94 in
> >>> > HBASE-4605<https://issues.apache.org/jira/browse/HBASE-4605>;
> >>> > they are almost ready to be rolled in, and backporting to 0.92 is
> >>> > definitely doable.
> >>> >
> >>> > However, Constraints aren't going to be quite flexible enough to
> >>> > efficiently support what you are describing. For instance, with a
> >>> > constraint, you are ideally just checking the put value against some
> >>> simple
> >>> > constraint (never over 10 or always an integer), but looking at the
> >>> current
> >>> > state of the table before allowing the put would currently require
> >>> creating
> >>> > a full blown connection to the local table through another HTable.
> >>> >
> >>> > In the short term, you could write a simple coprocessor to do this
> >>> checking
> >>> > and then move over to constraints (which are a simpler, more
> flexible,
> >>> way
> >>> > of doing this) when the necessary features have been added.
> >>> >
> >>> > It is worth discussing if it makes sense to have access to the local
> >>> region
> >>> > through a constraint, though that breaks the idea a little bit, it
> would
> >>> > certainly be useful and not overly wasteful in terms of runtime.
> >>> >
> >>> > Supposing the feature would be added to talk to the local table, and
> >>> since
> >>> > the puts are going to be serialized on the regionserver (at least to
> that
> >>> > single row you are trying to update), you will never get a situation
> >>> where
> >>> > the value added is over the threshold. If you were really worried
> about
> >>> the
> >>> > atomicity of the operation, then when doing the put, first get the
> >>> RowLock,
> >>> > then do the put and release the RowLock. However, that latter method
> is
> >>> > going to be really slow, so should only be used as a stop gap if the
> >>> > constraint doesn't work as expected, until a patch is made for
> >>> constraints.
> >>> >
> >>> > Feel free to open up a ticket and link it to 4605 for adding the
> local
> >>> > table access functionality, and we can discuss the de/merits of
> adding
> >>> the
> >>> > access.
> >>> >
> >>> > -Jesse
> >>> >
> >>> > On Sat, Dec 3, 2011 at 6:24 AM, Suraj Varma <svarma...@gmail.com>
> wrote:
> >>> >
> >>> >> I'm looking at the preCheckAndPut / postCheckAndPut api with
> >>> >> coprocessors and I'm wondering ... are these pre/post checks done
> >>> >> _after_ taking the row lock or is the row lock only done within the
> >>> >> checkAndPut api.
> >>> >>
> >>> >> I'm interested in seeing if we can implement something like:
> >>> >> (in pseudo sql)
> >>> >> update table-name
> >>> >> set column-name = new-value
> >>> >> where (column-value - new-value) > threshold-value
> >>> >>
> >>> >> Basically ... I want to enhance the checkAndPut to not just compare
> >>> >> "values" ... but apply an arbitrary function on the value
> _atomically_
> >>> >> in the Put call. Multiple threads would be firing these mutations
> and
> >>> >> I'd like the threshold-value above to never be breached under any
> >>> >> circumstance.
> >>> >>
> >>> >> Is there a solution that can be implemented either via checkAndPut
> or
> >>> >> using coprocessors preCheckAndPut? If not, would this be a useful
> >>> >> feature to build in HBase?
> >>> >>
> >>> >> Thanks,
> >>> >> --Suraj
> >>> >>
> >>> >
> >>> >
> >>> >
> >>> > --
> >>> > -------------------
> >>> > Jesse Yates
> >>> > 240-888-2200
> >>> > @jesse_yates
> >>>
>

Reply via email to