Skip to content

Commit 1002913

Browse files
authored
Final refactor of cancellation/timeout (#3318)
* The cancellation is no longer passed down the stack to the I/O layer; in all cases cancellation is done by registering a callback on the token. This unifies the flow for PG cancellation and non-PG cancellation. * Introduce notion of cancellable operations, which can contain nested cancellable operations. User actions implicitly represent a cancellable operation, making simple, one-operation cases very easy. * Make the up-front IsCancellationRequested check when starting a cancellable operation. This reduces the ceremony around each and every operation. * Various other refactoring to make the code simpler. Part of #3166
1 parent 05b20a3 commit 1002913

56 files changed

Lines changed: 781 additions & 832 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/Npgsql.GeoJSON/GeoJSONHandler.cs

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -125,48 +125,48 @@ static Exception AllOrNoneCoordiantesMustHaveZ(NpgsqlParameter? parameter, strin
125125

126126
#region Read
127127

128-
public override ValueTask<GeoJSONObject> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription = null, CancellationToken cancellationToken = default)
129-
=> ReadGeometry(buf, async, cancellationToken);
128+
public override ValueTask<GeoJSONObject> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription = null)
129+
=> ReadGeometry(buf, async);
130130

131-
async ValueTask<Point> INpgsqlTypeHandler<Point>.Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription, CancellationToken cancellationToken)
132-
=> (Point)await ReadGeometry(buf, async, cancellationToken);
131+
async ValueTask<Point> INpgsqlTypeHandler<Point>.Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription)
132+
=> (Point)await ReadGeometry(buf, async);
133133

134-
async ValueTask<LineString> INpgsqlTypeHandler<LineString>.Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription, CancellationToken cancellationToken)
135-
=> (LineString)await ReadGeometry(buf, async, cancellationToken);
134+
async ValueTask<LineString> INpgsqlTypeHandler<LineString>.Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription)
135+
=> (LineString)await ReadGeometry(buf, async);
136136

137-
async ValueTask<Polygon> INpgsqlTypeHandler<Polygon>.Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription, CancellationToken cancellationToken)
138-
=> (Polygon)await ReadGeometry(buf, async, cancellationToken);
137+
async ValueTask<Polygon> INpgsqlTypeHandler<Polygon>.Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription)
138+
=> (Polygon)await ReadGeometry(buf, async);
139139

140-
async ValueTask<MultiPoint> INpgsqlTypeHandler<MultiPoint>.Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription, CancellationToken cancellationToken)
141-
=> (MultiPoint)await ReadGeometry(buf, async, cancellationToken);
140+
async ValueTask<MultiPoint> INpgsqlTypeHandler<MultiPoint>.Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription)
141+
=> (MultiPoint)await ReadGeometry(buf, async);
142142

143-
async ValueTask<MultiLineString> INpgsqlTypeHandler<MultiLineString>.Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription, CancellationToken cancellationToken)
144-
=> (MultiLineString)await ReadGeometry(buf, async, cancellationToken);
143+
async ValueTask<MultiLineString> INpgsqlTypeHandler<MultiLineString>.Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription)
144+
=> (MultiLineString)await ReadGeometry(buf, async);
145145

146-
async ValueTask<MultiPolygon> INpgsqlTypeHandler<MultiPolygon>.Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription, CancellationToken cancellationToken)
147-
=> (MultiPolygon)await ReadGeometry(buf, async, cancellationToken);
146+
async ValueTask<MultiPolygon> INpgsqlTypeHandler<MultiPolygon>.Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription)
147+
=> (MultiPolygon)await ReadGeometry(buf, async);
148148

149-
async ValueTask<GeometryCollection> INpgsqlTypeHandler<GeometryCollection>.Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription, CancellationToken cancellationToken)
150-
=> (GeometryCollection)await ReadGeometry(buf, async, cancellationToken);
149+
async ValueTask<GeometryCollection> INpgsqlTypeHandler<GeometryCollection>.Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription)
150+
=> (GeometryCollection)await ReadGeometry(buf, async);
151151

152-
async ValueTask<IGeoJSONObject> INpgsqlTypeHandler<IGeoJSONObject>.Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription, CancellationToken cancellationToken)
153-
=> await ReadGeometry(buf, async, cancellationToken);
152+
async ValueTask<IGeoJSONObject> INpgsqlTypeHandler<IGeoJSONObject>.Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription)
153+
=> await ReadGeometry(buf, async);
154154

155-
async ValueTask<IGeometryObject> INpgsqlTypeHandler<IGeometryObject>.Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription, CancellationToken cancellationToken)
156-
=> (IGeometryObject)await ReadGeometry(buf, async, cancellationToken);
155+
async ValueTask<IGeometryObject> INpgsqlTypeHandler<IGeometryObject>.Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription)
156+
=> (IGeometryObject)await ReadGeometry(buf, async);
157157

158-
async ValueTask<GeoJSONObject> ReadGeometry(NpgsqlReadBuffer buf, bool async, CancellationToken cancellationToken = default)
158+
async ValueTask<GeoJSONObject> ReadGeometry(NpgsqlReadBuffer buf, bool async)
159159
{
160160
var boundingBox = BoundingBox ? new BoundingBoxBuilder() : null;
161-
var geometry = await ReadGeometryCore(buf, async, boundingBox, cancellationToken);
161+
var geometry = await ReadGeometryCore(buf, async, boundingBox);
162162

163163
geometry.BoundingBoxes = boundingBox?.Build();
164164
return geometry;
165165
}
166166

167-
async ValueTask<GeoJSONObject> ReadGeometryCore(NpgsqlReadBuffer buf, bool async, BoundingBoxBuilder? boundingBox, CancellationToken cancellationToken = default)
167+
async ValueTask<GeoJSONObject> ReadGeometryCore(NpgsqlReadBuffer buf, bool async, BoundingBoxBuilder? boundingBox)
168168
{
169-
await buf.Ensure(SizeOfHeader, async, cancellationToken);
169+
await buf.Ensure(SizeOfHeader, async);
170170
var littleEndian = buf.ReadByte() > 0;
171171
var type = (EwkbGeometryType)buf.ReadUInt32(littleEndian);
172172

@@ -175,15 +175,15 @@ async ValueTask<GeoJSONObject> ReadGeometryCore(NpgsqlReadBuffer buf, bool async
175175

176176
if (HasSrid(type))
177177
{
178-
await buf.Ensure(4, async, cancellationToken);
178+
await buf.Ensure(4, async);
179179
crs = GetCrs(buf.ReadInt32(littleEndian));
180180
}
181181

182182
switch (type & EwkbGeometryType.BaseType)
183183
{
184184
case EwkbGeometryType.Point:
185185
{
186-
await buf.Ensure(SizeOfPoint(type), async, cancellationToken);
186+
await buf.Ensure(SizeOfPoint(type), async);
187187
var position = ReadPosition(buf, type, littleEndian);
188188
boundingBox?.Accumulate(position);
189189
geometry = new Point(position);
@@ -192,11 +192,11 @@ async ValueTask<GeoJSONObject> ReadGeometryCore(NpgsqlReadBuffer buf, bool async
192192

193193
case EwkbGeometryType.LineString:
194194
{
195-
await buf.Ensure(SizeOfLength, async, cancellationToken);
195+
await buf.Ensure(SizeOfLength, async);
196196
var coordinates = new Position[buf.ReadInt32(littleEndian)];
197197
for (var i = 0; i < coordinates.Length; ++i)
198198
{
199-
await buf.Ensure(SizeOfPoint(type), async, cancellationToken);
199+
await buf.Ensure(SizeOfPoint(type), async);
200200
var position = ReadPosition(buf, type, littleEndian);
201201
boundingBox?.Accumulate(position);
202202
coordinates[i] = position;
@@ -207,14 +207,14 @@ async ValueTask<GeoJSONObject> ReadGeometryCore(NpgsqlReadBuffer buf, bool async
207207

208208
case EwkbGeometryType.Polygon:
209209
{
210-
await buf.Ensure(SizeOfLength, async, cancellationToken);
210+
await buf.Ensure(SizeOfLength, async);
211211
var lines = new LineString[buf.ReadInt32(littleEndian)];
212212
for (var i = 0; i < lines.Length; ++i)
213213
{
214214
var coordinates = new Position[buf.ReadInt32(littleEndian)];
215215
for (var j = 0; j < coordinates.Length; ++j)
216216
{
217-
await buf.Ensure(SizeOfPoint(type), async, cancellationToken);
217+
await buf.Ensure(SizeOfPoint(type), async);
218218
var position = ReadPosition(buf, type, littleEndian);
219219
boundingBox?.Accumulate(position);
220220
coordinates[j] = position;
@@ -227,12 +227,12 @@ async ValueTask<GeoJSONObject> ReadGeometryCore(NpgsqlReadBuffer buf, bool async
227227

228228
case EwkbGeometryType.MultiPoint:
229229
{
230-
await buf.Ensure(SizeOfLength, async, cancellationToken);
230+
await buf.Ensure(SizeOfLength, async);
231231
var points = new Point[buf.ReadInt32(littleEndian)];
232232
for (var i = 0; i < points.Length; ++i)
233233
{
234-
await buf.Ensure(SizeOfHeader + SizeOfPoint(type), async, cancellationToken);
235-
await buf.Skip(SizeOfHeader, async, cancellationToken);
234+
await buf.Ensure(SizeOfHeader + SizeOfPoint(type), async);
235+
await buf.Skip(SizeOfHeader, async);
236236
var position = ReadPosition(buf, type, littleEndian);
237237
boundingBox?.Accumulate(position);
238238
points[i] = new Point(position);
@@ -243,16 +243,16 @@ async ValueTask<GeoJSONObject> ReadGeometryCore(NpgsqlReadBuffer buf, bool async
243243

244244
case EwkbGeometryType.MultiLineString:
245245
{
246-
await buf.Ensure(SizeOfLength, async, cancellationToken);
246+
await buf.Ensure(SizeOfLength, async);
247247
var lines = new LineString[buf.ReadInt32(littleEndian)];
248248
for (var i = 0; i < lines.Length; ++i)
249249
{
250-
await buf.Ensure(SizeOfHeaderWithLength, async, cancellationToken);
251-
await buf.Skip(SizeOfHeader, async, cancellationToken);
250+
await buf.Ensure(SizeOfHeaderWithLength, async);
251+
await buf.Skip(SizeOfHeader, async);
252252
var coordinates = new Position[buf.ReadInt32(littleEndian)];
253253
for (var j = 0; j < coordinates.Length; ++j)
254254
{
255-
await buf.Ensure(SizeOfPoint(type), async, cancellationToken);
255+
await buf.Ensure(SizeOfPoint(type), async);
256256
var position = ReadPosition(buf, type, littleEndian);
257257
boundingBox?.Accumulate(position);
258258
coordinates[j] = position;
@@ -265,19 +265,19 @@ async ValueTask<GeoJSONObject> ReadGeometryCore(NpgsqlReadBuffer buf, bool async
265265

266266
case EwkbGeometryType.MultiPolygon:
267267
{
268-
await buf.Ensure(SizeOfLength, async, cancellationToken);
268+
await buf.Ensure(SizeOfLength, async);
269269
var polygons = new Polygon[buf.ReadInt32(littleEndian)];
270270
for (var i = 0; i < polygons.Length; ++i)
271271
{
272-
await buf.Ensure(SizeOfHeaderWithLength, async, cancellationToken);
273-
await buf.Skip(SizeOfHeader, async, cancellationToken);
272+
await buf.Ensure(SizeOfHeaderWithLength, async);
273+
await buf.Skip(SizeOfHeader, async);
274274
var lines = new LineString[buf.ReadInt32(littleEndian)];
275275
for (var j = 0; j < lines.Length; ++j)
276276
{
277277
var coordinates = new Position[buf.ReadInt32(littleEndian)];
278278
for (var k = 0; k < coordinates.Length; ++k)
279279
{
280-
await buf.Ensure(SizeOfPoint(type), async, cancellationToken);
280+
await buf.Ensure(SizeOfPoint(type), async);
281281
var position = ReadPosition(buf, type, littleEndian);
282282
boundingBox?.Accumulate(position);
283283
coordinates[k] = position;
@@ -292,10 +292,10 @@ async ValueTask<GeoJSONObject> ReadGeometryCore(NpgsqlReadBuffer buf, bool async
292292

293293
case EwkbGeometryType.GeometryCollection:
294294
{
295-
await buf.Ensure(SizeOfLength, async, cancellationToken);
295+
await buf.Ensure(SizeOfLength, async);
296296
var elements = new IGeometryObject[buf.ReadInt32(littleEndian)];
297297
for (var i = 0; i < elements.Length; ++i)
298-
elements[i] = (IGeometryObject)await ReadGeometryCore(buf, async, boundingBox, cancellationToken);
298+
elements[i] = (IGeometryObject)await ReadGeometryCore(buf, async, boundingBox);
299299
geometry = new GeometryCollection(elements);
300300
break;
301301
}

src/Npgsql.Json.NET/JsonHandler.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,18 @@ class JsonHandler : TypeHandlers.TextHandler
2828
public JsonHandler(PostgresType postgresType, NpgsqlConnection connection, JsonSerializerSettings settings)
2929
: base(postgresType, connection) => _settings = settings;
3030

31-
protected override async ValueTask<T> Read<T>(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription = null, CancellationToken cancellationToken = default)
31+
protected override async ValueTask<T> Read<T>(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription = null)
3232
{
3333
if (typeof(T) == typeof(string) ||
3434
typeof(T) == typeof(char[]) ||
3535
typeof(T) == typeof(ArraySegment<char>) ||
3636
typeof(T) == typeof(char) ||
3737
typeof(T) == typeof(byte[]))
3838
{
39-
return await base.Read<T>(buf, len, async, fieldDescription, cancellationToken);
39+
return await base.Read<T>(buf, len, async, fieldDescription);
4040
}
4141

42-
return JsonConvert.DeserializeObject<T>(await base.Read<string>(buf, len, async, fieldDescription, cancellationToken), _settings);
42+
return JsonConvert.DeserializeObject<T>(await base.Read<string>(buf, len, async, fieldDescription), _settings);
4343
}
4444

4545
protected override int ValidateAndGetLength<T2>(T2 value, ref NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter)

src/Npgsql.Json.NET/JsonbHandler.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,18 @@ class JsonbHandler : Npgsql.TypeHandlers.JsonHandler
2828
public JsonbHandler(PostgresType postgresType, NpgsqlConnection connection, JsonSerializerSettings settings)
2929
: base(postgresType, connection, isJsonb: true) => _settings = settings;
3030

31-
protected override async ValueTask<T> Read<T>(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription = null, CancellationToken cancellationToken = default)
31+
protected override async ValueTask<T> Read<T>(NpgsqlReadBuffer buf, int len, bool async, FieldDescription? fieldDescription = null)
3232
{
3333
if (typeof(T) == typeof(string) ||
3434
typeof(T) == typeof(char[]) ||
3535
typeof(T) == typeof(ArraySegment<char>) ||
3636
typeof(T) == typeof(char) ||
3737
typeof(T) == typeof(byte[]))
3838
{
39-
return await base.Read<T>(buf, len, async, fieldDescription, cancellationToken);
39+
return await base.Read<T>(buf, len, async, fieldDescription);
4040
}
4141

42-
return JsonConvert.DeserializeObject<T>(await base.Read<string>(buf, len, async, fieldDescription, cancellationToken), _settings);
42+
return JsonConvert.DeserializeObject<T>(await base.Read<string>(buf, len, async, fieldDescription), _settings);
4343
}
4444

4545
protected override int ValidateAndGetLength<T2>(T2 value, ref NpgsqlLengthCache? lengthCache, NpgsqlParameter? parameter)

0 commit comments

Comments
 (0)