Kodey Converse created HBASE-29850:
--------------------------------------

             Summary: Add support for dynamic per-request attributes in 
AsyncTable
                 Key: HBASE-29850
                 URL: https://issues.apache.org/jira/browse/HBASE-29850
             Project: HBase
          Issue Type: Improvement
          Components: Client
            Reporter: Kodey Converse


Some request attributes are useful to set on a per-request basis rather than 
statically on the client. For example, when {{hbase.quota.user.override.key}} 
is configured, the corresponding request attribute can override the effective 
user for quota/throttling purposes. With dynamic request attributes, users can 
set up throttles on arbitrary callers coming into the system.

A use case for this at my company, which we utilize heavily, is propagating the 
original caller through HTTP thread metadata when requests jump through 
multiple HTTP servers before reaching HBase. This allows throttling the 
original caller rather than the service making the HBase call.

For the synchronous {{Table}} interface, it's already possible to generate 
request attributes per-request by overriding {{RpcControllerFactory}} and 
generating the request attributes dynamically in 
{{{}HBaseRpcController.getRequestAttributes(){}}}. However, that doesn't work 
with {{{}AsyncTable{}}}, because when requests are retried automatically, the 
{{RpcControllerFactory}} is called from within a netty thread and not on the 
client's original thread, so the attributes can't reliably use thread locals to 
generate the attributes.

This change introduces support for dynamic request attributes by adding a 
{{RequestAttributesFactory}} interface. The factory is called on each request, 
receives the static attributes configured on the table, and can return 
modified/augmented attributes for that specific request.
h3. API Addition
{code:java}
public interface RequestAttributesFactory {
  Map<String, byte[]> create(Map<String, byte[]> requestAttributes);
}

// Usage
AsyncTable<?> table = conn.getTableBuilder(tableName)
  .setRequestAttributesFactory(attrs -> {
    Map<String, byte[]> newAttrs = new HashMap<>(attrs);
    newAttrs.put("hbase.user", getCurrentUserFromThreadContext());
    return newAttrs;
  })
  .build();
{code}
The factory is guaranteed to be called on the same thread that initiates the 
client call, making it safe to read thread-local context.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to