0
# Immutable State Types
1
2
Read-only state wrappers returned from queries that provide access to state values while preventing modifications. All state objects returned by the queryable state client are immutable - any attempt to modify them will throw `UnsupportedOperationException`.
3
4
## Capabilities
5
6
### ImmutableValueState
7
8
Read-only wrapper for ValueState that contains a single value.
9
10
```java { .api }
11
public final class ImmutableValueState<V> implements ValueState<V> {
12
public V value();
13
public void update(V newValue); // Throws UnsupportedOperationException
14
public void clear(); // Throws UnsupportedOperationException
15
}
16
```
17
18
**Methods:**
19
- `value()` - Returns the stored value (never null)
20
- `update(V)` - Always throws UnsupportedOperationException
21
- `clear()` - Always throws UnsupportedOperationException
22
23
**Usage Example:**
24
```java
25
CompletableFuture<ValueState<String>> future = client.getKvState(
26
jobId, stateName, key, TypeInformation.of(String.class),
27
new ValueStateDescriptor<>("state", String.class)
28
);
29
30
future.thenAccept(state -> {
31
String value = state.value(); // OK - read access
32
System.out.println("Value: " + value);
33
34
// state.update("new value"); // Would throw UnsupportedOperationException
35
// state.clear(); // Would throw UnsupportedOperationException
36
});
37
```
38
39
### ImmutableListState
40
41
Read-only wrapper for ListState that contains a list of values.
42
43
```java { .api }
44
public final class ImmutableListState<V> implements ListState<V> {
45
public Iterable<V> get();
46
public void add(V value); // Throws UnsupportedOperationException
47
public void update(List<V> values); // Throws UnsupportedOperationException
48
public void addAll(List<V> values); // Throws UnsupportedOperationException
49
public void clear(); // Throws UnsupportedOperationException
50
}
51
```
52
53
**Methods:**
54
- `get()` - Returns an Iterable over the list values (read-only)
55
- All modification methods throw UnsupportedOperationException
56
57
**Usage Example:**
58
```java
59
CompletableFuture<ListState<Integer>> future = client.getKvState(
60
jobId, stateName, key, TypeInformation.of(String.class),
61
new ListStateDescriptor<>("numbers", Integer.class)
62
);
63
64
future.thenAccept(state -> {
65
Iterable<Integer> values = state.get(); // OK - read access
66
for (Integer value : values) {
67
System.out.println("Value: " + value);
68
}
69
70
// state.add(42); // Would throw UnsupportedOperationException
71
// state.clear(); // Would throw UnsupportedOperationException
72
});
73
```
74
75
### ImmutableMapState
76
77
Read-only wrapper for MapState that contains key-value mappings.
78
79
```java { .api }
80
public final class ImmutableMapState<K, V> implements MapState<K, V> {
81
public V get(K key);
82
public boolean contains(K key);
83
public Iterable<Map.Entry<K, V>> entries();
84
public Iterable<K> keys();
85
public Iterable<V> values();
86
public Iterator<Map.Entry<K, V>> iterator();
87
public boolean isEmpty();
88
89
public void put(K key, V value); // Throws UnsupportedOperationException
90
public void putAll(Map<K, V> map); // Throws UnsupportedOperationException
91
public void remove(K key); // Throws UnsupportedOperationException
92
public void clear(); // Throws UnsupportedOperationException
93
}
94
```
95
96
**Read Methods:**
97
- `get(K key)` - Returns the value for the given key, or null if not present
98
- `contains(K key)` - Returns true if the key exists in the map
99
- `entries()` - Returns an Iterable over all key-value pairs (read-only)
100
- `keys()` - Returns an Iterable over all keys (read-only)
101
- `values()` - Returns an Iterable over all values (read-only)
102
- `iterator()` - Returns a read-only Iterator over all entries
103
- `isEmpty()` - Returns true if the map contains no entries
104
105
**Usage Example:**
106
```java
107
CompletableFuture<MapState<String, Long>> future = client.getKvState(
108
jobId, stateName, key, TypeInformation.of(String.class),
109
new MapStateDescriptor<>("counters", String.class, Long.class)
110
);
111
112
future.thenAccept(state -> {
113
// Read operations - all OK
114
Long count = state.get("clicks");
115
boolean hasClicks = state.contains("clicks");
116
117
if (!state.isEmpty()) {
118
for (Map.Entry<String, Long> entry : state.entries()) {
119
System.out.println(entry.getKey() + ": " + entry.getValue());
120
}
121
}
122
123
// state.put("new", 100L); // Would throw UnsupportedOperationException
124
// state.remove("clicks"); // Would throw UnsupportedOperationException
125
});
126
```
127
128
### ImmutableReducingState
129
130
Read-only wrapper for ReducingState that contains a reduced value.
131
132
```java { .api }
133
public final class ImmutableReducingState<V> implements ReducingState<V> {
134
public V get();
135
public void add(V newValue); // Throws UnsupportedOperationException
136
public void clear(); // Throws UnsupportedOperationException
137
}
138
```
139
140
**Methods:**
141
- `get()` - Returns the reduced value, or null if no values were added
142
- All modification methods throw UnsupportedOperationException
143
144
**Usage Example:**
145
```java
146
CompletableFuture<ReducingState<Integer>> future = client.getKvState(
147
jobId, stateName, key, TypeInformation.of(String.class),
148
new ReducingStateDescriptor<>("sum", Integer::sum, Integer.class)
149
);
150
151
future.thenAccept(state -> {
152
Integer sum = state.get(); // OK - read access
153
System.out.println("Sum: " + sum);
154
155
// state.add(10); // Would throw UnsupportedOperationException
156
});
157
```
158
159
### ImmutableAggregatingState
160
161
Read-only wrapper for AggregatingState that contains an aggregated result.
162
163
```java { .api }
164
public final class ImmutableAggregatingState<IN, OUT> implements AggregatingState<IN, OUT> {
165
public OUT get();
166
public void add(Object newValue); // Throws UnsupportedOperationException
167
public void clear(); // Throws UnsupportedOperationException
168
}
169
```
170
171
**Methods:**
172
- `get()` - Returns the aggregated result, or null if no values were aggregated
173
- All modification methods throw UnsupportedOperationException
174
175
**Usage Example:**
176
```java
177
// Assuming an AggregateFunction that takes Integer input and produces Double output
178
CompletableFuture<AggregatingState<Integer, Double>> future = client.getKvState(
179
jobId, stateName, key, TypeInformation.of(String.class),
180
new AggregatingStateDescriptor<>("average", avgFunction, Double.class)
181
);
182
183
future.thenAccept(state -> {
184
Double average = state.get(); // OK - read access
185
System.out.println("Average: " + average);
186
187
// state.add(5); // Would throw UnsupportedOperationException
188
});
189
```
190
191
## Immutability Enforcement
192
193
All immutable state classes extend the abstract `ImmutableState` class, which provides:
194
195
```java { .api }
196
public abstract class ImmutableState {
197
protected static final UnsupportedOperationException MODIFICATION_ATTEMPT_ERROR;
198
}
199
```
200
201
This shared constant is thrown by all modification methods to provide consistent error messages when attempting to modify read-only state.
202
203
## State Creation
204
205
Immutable state objects are created internally by the QueryableStateClient using factory methods:
206
207
```java { .api }
208
// Factory methods (internal usage)
209
public static <V, S extends State> S createState(
210
StateDescriptor<S, V> stateDescriptor,
211
byte[] serializedState
212
) throws Exception;
213
```
214
215
These factory methods deserialize the state data received from the Flink cluster and wrap it in the appropriate immutable state implementation.
216
217
## Thread Safety
218
219
All immutable state objects are thread-safe for read operations since they cannot be modified after creation. Multiple threads can safely call read methods (like `value()`, `get()`, `entries()`, etc.) concurrently without synchronization.