DUE TO SPAM, SIGN-UP IS DISABLED. Goto Selfserve wiki signup and request an account.
DUE TO SPAM, SIGN-UP IS DISABLED. Goto Selfserve wiki signup and request an account.
| ID | IEP-126 |
| Author | |
| Sponsor | |
| Created | 10.09.2024 |
| Status | DRAFT |
When processing data, users want to have access to non-tabular (not stored in cache structures) data. Example of such data is application attributes - an associative array specified on an application side. Usage scenarios:
CacheInterceptor extracts the user from the attributes and saves it along with data).QuerySqlFunction use the same parameter and it is convenient to take it from the attributes, rather than transfer it separately to each function).Another examples of non-tabular data that can be accessed are SecuritySubject, UserAttributes and current Transaction.
The requirements include:
QuerySqlFunction, CacheInterceptor).Ignite does not have a similar public API:
ServiceCallContext helps solve similar problems, but has several limitations. The main one is that it is only available in calls via the IgniteService API and cannot be used for single operations or transactions.UserAttributes - allows to set user attributes, but the attribute values are fixed for the entire lifetime of the connection.ClientListenerConnectionContext - it's available only on single node, which accepts connection from a client.A similar context mechanism exists in Oracle [1] and it's widely used.
ApplicationContext is an entrypoint for accessing all non-tabular data.QuerySqlFunction are static, CacheInterceptor is a singleton for cache)./** ApplicationContext interface. It's an entrypoint for all non-tabular information. */
public class ApplicationContext {
/** @return Application attributes set for current thread. */
public static @Nullable Map<String, String> getAttributes();
}
/** Example, use it in QuerySqlFunction. */
public static class UserDefinedFunctions {
/** @return Session ID, application attribute. */
@QuerySqlFunction
public static String sessionId() {
Map<String, String> appAttrs = ApplicationContext.getAttributes();
return appAttrs == null ? null : appAttr.get(SESSION_ID);
}
}
Ignite instance from multiple threads by different applications. Also the same thread can be shared between multiple applications.ApplicationContext should not depend on the used API.// Extends the interface with new public method.
public interface IgniteTransactions {
...
/** @param appAttrs Application attributes. */
public IgniteTransactions withApplicationAttributes(Map<String, String> appAttrs);
}
// Example of usage.
try (Ignite ign = Ignition.localIgnite()) {
Map<String, String> appAttrs = F.asMap("SESSION_ID", "1234");
try (Transaction tx = ign.transactions().withApplicationAttributes(appAttrs).txStart()) {
...
}
}
Ignite node.ClientBitmaskFeature protocol.// Extends the interface with new public method.
public interface ClientTransactions {
...
/** @param appAttrs Application attributes. */
public ClientTransactions withApplicationAttributes(Map<String, String> appAttrs);
}
// Example of usage.
try (IgniteClient cln = Ignition.startClient(clnCfg)) {
Map<String, String> appAttrs = F.asMap("SESSION_ID", "1234");
try (ClientTransaction tx = cln.transactions().withApplicationAttributes(appAttrs).txStart()) {
...
}
}
The standard jdbc protocol describes the methods Connection#setClientInfo, which allow changing the values of client attributes during the life of the connection [3]. Implementation features:
#setClientInfo is arbitrary. The documentation recommends strictly limiting the set of attributes, but this is not necessary. For example, Oracle does not have such a limitation [5]. The setClientInfo array is completely translated into the getClientAttributes array.setClientInfo are passed along with each JdbcRequest (this requires a new feature in JdbcThinFeature).// JDBC connection to Ignite server.
try (Connection conn = DriverManager.getConnection(URL)) {
conn.setClientInfo("SESSION_ID", "1234");
...
}
QueryStartRequest SQL message protocol (for jdbc, SQL transactions)CacheInterceptor), since inserts are not always performed on the request initiator node.// Describe project risks, such as API or binary compatibility issues, major protocol changes, etc.
// Links to discussions on the devlist, if applicable.
[4] https://torofimofu.blogspot.com/2014/05/oracle.html
[5] https://docs.oracle.com/database/121/JJDBC/jdbcvers.htm#BABDAEEC
// Links or report with relevant JIRA tickets.