or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client-management.mdexception-handling.mdimmutable-state.mdindex.mdstate-querying.md

immutable-state.mddocs/

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.