Skip to content

Commit 15303c5

Browse files
author
Bart Koelman
authored
Added request cancellation support (#879)
* Removed unused methods * Added request cancellation support
1 parent baa1802 commit 15303c5

38 files changed

+448
-348
lines changed

src/Examples/JsonApiDotNetCoreExample/Controllers/TodoCollectionsController.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Linq;
3+
using System.Threading;
34
using System.Threading.Tasks;
45
using JsonApiDotNetCore.Configuration;
56
using JsonApiDotNetCore.Controllers;
@@ -27,15 +28,16 @@ public TodoCollectionsController(
2728
}
2829

2930
[HttpPatch("{id}")]
30-
public override async Task<IActionResult> PatchAsync(Guid id, [FromBody] TodoItemCollection resource)
31+
public override async Task<IActionResult> PatchAsync(Guid id, [FromBody] TodoItemCollection resource, CancellationToken cancellationToken)
3132
{
3233
if (resource.Name == "PRE-ATTACH-TEST")
3334
{
3435
var targetTodoId = resource.TodoItems.First().Id;
3536
var todoItemContext = _dbResolver.GetContext().Set<TodoItem>();
36-
await todoItemContext.Where(ti => ti.Id == targetTodoId).FirstOrDefaultAsync();
37+
await todoItemContext.Where(ti => ti.Id == targetTodoId).FirstOrDefaultAsync(cancellationToken);
3738
}
38-
return await base.PatchAsync(id, resource);
39+
40+
return await base.PatchAsync(id, resource, cancellationToken);
3941
}
4042

4143
}

src/Examples/JsonApiDotNetCoreExample/Controllers/TodoItemsCustomController.cs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Net;
2+
using System.Threading;
23
using System.Threading.Tasks;
34
using JsonApiDotNetCore.Configuration;
45
using JsonApiDotNetCore.Controllers.Annotations;
@@ -58,18 +59,18 @@ public CustomJsonApiController(
5859
}
5960

6061
[HttpGet]
61-
public async Task<IActionResult> GetAsync()
62+
public async Task<IActionResult> GetAsync(CancellationToken cancellationToken)
6263
{
63-
var resources = await _resourceService.GetAsync();
64+
var resources = await _resourceService.GetAsync(cancellationToken);
6465
return Ok(resources);
6566
}
6667

6768
[HttpGet("{id}")]
68-
public async Task<IActionResult> GetAsync(TId id)
69+
public async Task<IActionResult> GetAsync(TId id, CancellationToken cancellationToken)
6970
{
7071
try
7172
{
72-
var resource = await _resourceService.GetAsync(id);
73+
var resource = await _resourceService.GetAsync(id, cancellationToken);
7374
return Ok(resource);
7475
}
7576
catch (ResourceNotFoundException)
@@ -79,11 +80,11 @@ public async Task<IActionResult> GetAsync(TId id)
7980
}
8081

8182
[HttpGet("{id}/relationships/{relationshipName}")]
82-
public async Task<IActionResult> GetRelationshipsAsync(TId id, string relationshipName)
83+
public async Task<IActionResult> GetRelationshipsAsync(TId id, string relationshipName, CancellationToken cancellationToken)
8384
{
8485
try
8586
{
86-
var relationship = await _resourceService.GetRelationshipAsync(id, relationshipName);
87+
var relationship = await _resourceService.GetRelationshipAsync(id, relationshipName, cancellationToken);
8788
return Ok(relationship);
8889
}
8990
catch (ResourceNotFoundException)
@@ -93,35 +94,35 @@ public async Task<IActionResult> GetRelationshipsAsync(TId id, string relationsh
9394
}
9495

9596
[HttpGet("{id}/{relationshipName}")]
96-
public async Task<IActionResult> GetRelationshipAsync(TId id, string relationshipName)
97+
public async Task<IActionResult> GetRelationshipAsync(TId id, string relationshipName, CancellationToken cancellationToken)
9798
{
98-
var relationship = await _resourceService.GetSecondaryAsync(id, relationshipName);
99+
var relationship = await _resourceService.GetSecondaryAsync(id, relationshipName, cancellationToken);
99100
return Ok(relationship);
100101
}
101102

102103
[HttpPost]
103-
public async Task<IActionResult> PostAsync([FromBody] T resource)
104+
public async Task<IActionResult> PostAsync([FromBody] T resource, CancellationToken cancellationToken)
104105
{
105106
if (resource == null)
106107
return UnprocessableEntity();
107108

108109
if (_options.AllowClientGeneratedIds && !string.IsNullOrEmpty(resource.StringId))
109110
return Forbidden();
110111

111-
resource = await _resourceService.CreateAsync(resource);
112+
resource = await _resourceService.CreateAsync(resource, cancellationToken);
112113

113114
return Created($"{HttpContext.Request.Path}/{resource.Id}", resource);
114115
}
115116

116117
[HttpPatch("{id}")]
117-
public async Task<IActionResult> PatchAsync(TId id, [FromBody] T resource)
118+
public async Task<IActionResult> PatchAsync(TId id, [FromBody] T resource, CancellationToken cancellationToken)
118119
{
119120
if (resource == null)
120121
return UnprocessableEntity();
121122

122123
try
123124
{
124-
var updated = await _resourceService.UpdateAsync(id, resource);
125+
var updated = await _resourceService.UpdateAsync(id, resource, cancellationToken);
125126
return Ok(updated);
126127
}
127128
catch (ResourceNotFoundException)
@@ -131,17 +132,17 @@ public async Task<IActionResult> PatchAsync(TId id, [FromBody] T resource)
131132
}
132133

133134
[HttpPatch("{id}/relationships/{relationshipName}")]
134-
public async Task<IActionResult> PatchRelationshipAsync(TId id, string relationshipName, [FromBody] object secondaryResourceIds)
135+
public async Task<IActionResult> PatchRelationshipAsync(TId id, string relationshipName, [FromBody] object secondaryResourceIds, CancellationToken cancellationToken)
135136
{
136-
await _resourceService.SetRelationshipAsync(id, relationshipName, secondaryResourceIds);
137+
await _resourceService.SetRelationshipAsync(id, relationshipName, secondaryResourceIds, cancellationToken);
137138

138139
return Ok();
139140
}
140141

141142
[HttpDelete("{id}")]
142-
public async Task<IActionResult> DeleteAsync(TId id)
143+
public async Task<IActionResult> DeleteAsync(TId id, CancellationToken cancellationToken)
143144
{
144-
await _resourceService.DeleteAsync(id);
145+
await _resourceService.DeleteAsync(id, cancellationToken);
145146
return NoContent();
146147
}
147148
}

src/Examples/JsonApiDotNetCoreExample/Controllers/TodoItemsTestController.cs

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.Net;
3+
using System.Threading;
34
using System.Threading.Tasks;
45
using JsonApiDotNetCore.Configuration;
56
using JsonApiDotNetCore.Controllers;
@@ -36,21 +37,31 @@ public TodoItemsTestController(
3637
{ }
3738

3839
[HttpGet]
39-
public override async Task<IActionResult> GetAsync() => await base.GetAsync();
40+
public override async Task<IActionResult> GetAsync(CancellationToken cancellationToken)
41+
{
42+
return await base.GetAsync(cancellationToken);
43+
}
4044

4145
[HttpGet("{id}")]
42-
public override async Task<IActionResult> GetAsync(int id) => await base.GetAsync(id);
46+
public override async Task<IActionResult> GetAsync(int id, CancellationToken cancellationToken)
47+
{
48+
return await base.GetAsync(id, cancellationToken);
49+
}
4350

4451
[HttpGet("{id}/{relationshipName}")]
45-
public override async Task<IActionResult> GetSecondaryAsync(int id, string relationshipName)
46-
=> await base.GetSecondaryAsync(id, relationshipName);
52+
public override async Task<IActionResult> GetSecondaryAsync(int id, string relationshipName, CancellationToken cancellationToken)
53+
{
54+
return await base.GetSecondaryAsync(id, relationshipName, cancellationToken);
55+
}
4756

4857
[HttpGet("{id}/relationships/{relationshipName}")]
49-
public override async Task<IActionResult> GetRelationshipAsync(int id, string relationshipName)
50-
=> await base.GetRelationshipAsync(id, relationshipName);
58+
public override async Task<IActionResult> GetRelationshipAsync(int id, string relationshipName, CancellationToken cancellationToken)
59+
{
60+
return await base.GetRelationshipAsync(id, relationshipName, cancellationToken);
61+
}
5162

5263
[HttpPost]
53-
public override async Task<IActionResult> PostAsync([FromBody] TodoItem resource)
64+
public override async Task<IActionResult> PostAsync([FromBody] TodoItem resource, CancellationToken cancellationToken)
5465
{
5566
await Task.Yield();
5667

@@ -62,11 +73,13 @@ public override async Task<IActionResult> PostAsync([FromBody] TodoItem resource
6273

6374
[HttpPost("{id}/relationships/{relationshipName}")]
6475
public override async Task<IActionResult> PostRelationshipAsync(
65-
int id, string relationshipName, [FromBody] ISet<IIdentifiable> secondaryResourceIds)
66-
=> await base.PostRelationshipAsync(id, relationshipName, secondaryResourceIds);
76+
int id, string relationshipName, [FromBody] ISet<IIdentifiable> secondaryResourceIds, CancellationToken cancellationToken)
77+
{
78+
return await base.PostRelationshipAsync(id, relationshipName, secondaryResourceIds, cancellationToken);
79+
}
6780

6881
[HttpPatch("{id}")]
69-
public override async Task<IActionResult> PatchAsync(int id, [FromBody] TodoItem resource)
82+
public override async Task<IActionResult> PatchAsync(int id, [FromBody] TodoItem resource, CancellationToken cancellationToken)
7083
{
7184
await Task.Yield();
7285

@@ -75,19 +88,23 @@ public override async Task<IActionResult> PatchAsync(int id, [FromBody] TodoItem
7588

7689
[HttpPatch("{id}/relationships/{relationshipName}")]
7790
public override async Task<IActionResult> PatchRelationshipAsync(
78-
int id, string relationshipName, [FromBody] object secondaryResourceIds)
79-
=> await base.PatchRelationshipAsync(id, relationshipName, secondaryResourceIds);
91+
int id, string relationshipName, [FromBody] object secondaryResourceIds, CancellationToken cancellationToken)
92+
{
93+
return await base.PatchRelationshipAsync(id, relationshipName, secondaryResourceIds, cancellationToken);
94+
}
8095

8196
[HttpDelete("{id}")]
82-
public override async Task<IActionResult> DeleteAsync(int id)
97+
public override async Task<IActionResult> DeleteAsync(int id, CancellationToken cancellationToken)
8398
{
8499
await Task.Yield();
85100

86101
return NotFound();
87102
}
88103

89104
[HttpDelete("{id}/relationships/{relationshipName}")]
90-
public override async Task<IActionResult> DeleteRelationshipAsync(int id, string relationshipName, [FromBody] ISet<IIdentifiable> secondaryResourceIds)
91-
=> await base.DeleteRelationshipAsync(id, relationshipName, secondaryResourceIds);
105+
public override async Task<IActionResult> DeleteRelationshipAsync(int id, string relationshipName, [FromBody] ISet<IIdentifiable> secondaryResourceIds, CancellationToken cancellationToken)
106+
{
107+
return await base.DeleteRelationshipAsync(id, relationshipName, secondaryResourceIds, cancellationToken);
108+
}
92109
}
93110
}

src/Examples/JsonApiDotNetCoreExample/Services/CustomArticleService.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Threading;
12
using System.Threading.Tasks;
23
using JsonApiDotNetCore.Configuration;
34
using JsonApiDotNetCore.Hooks.Internal;
@@ -27,9 +28,9 @@ public CustomArticleService(
2728
resourceChangeTracker, resourceFactory, hookExecutor)
2829
{ }
2930

30-
public override async Task<Article> GetAsync(int id)
31+
public override async Task<Article> GetAsync(int id, CancellationToken cancellationToken)
3132
{
32-
var resource = await base.GetAsync(id);
33+
var resource = await base.GetAsync(id, cancellationToken);
3334
resource.Caption = "None for you Glen Coco";
3435
return resource;
3536
}

src/Examples/NoEntityFrameworkExample/Services/WorkItemService.cs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Data;
44
using System.Linq;
5+
using System.Threading;
56
using System.Threading.Tasks;
67
using Dapper;
78
using JsonApiDotNetCore.Resources;
@@ -22,67 +23,67 @@ public WorkItemService(IConfiguration configuration)
2223
_connectionString = configuration["Data:DefaultConnection"].Replace("###", postgresPassword);
2324
}
2425

25-
public async Task<IReadOnlyCollection<WorkItem>> GetAsync()
26+
public async Task<IReadOnlyCollection<WorkItem>> GetAsync(CancellationToken cancellationToken)
2627
{
2728
return (await QueryAsync(async connection =>
28-
await connection.QueryAsync<WorkItem>(@"select * from ""WorkItems"""))).ToList();
29+
await connection.QueryAsync<WorkItem>(new CommandDefinition(@"select * from ""WorkItems""", cancellationToken: cancellationToken)))).ToList();
2930
}
3031

31-
public async Task<WorkItem> GetAsync(int id)
32+
public async Task<WorkItem> GetAsync(int id, CancellationToken cancellationToken)
3233
{
3334
var query = await QueryAsync(async connection =>
34-
await connection.QueryAsync<WorkItem>(@"select * from ""WorkItems"" where ""Id""=@id", new {id}));
35+
await connection.QueryAsync<WorkItem>(new CommandDefinition(@"select * from ""WorkItems"" where ""Id""=@id", new {id}, cancellationToken: cancellationToken)));
3536

3637
return query.Single();
3738
}
3839

39-
public Task<object> GetSecondaryAsync(int id, string relationshipName)
40+
public Task<object> GetSecondaryAsync(int id, string relationshipName, CancellationToken cancellationToken)
4041
{
4142
throw new NotImplementedException();
4243
}
4344

44-
public Task<object> GetRelationshipAsync(int id, string relationshipName)
45+
public Task<object> GetRelationshipAsync(int id, string relationshipName, CancellationToken cancellationToken)
4546
{
4647
throw new NotImplementedException();
4748
}
4849

49-
public async Task<WorkItem> CreateAsync(WorkItem resource)
50+
public async Task<WorkItem> CreateAsync(WorkItem resource, CancellationToken cancellationToken)
5051
{
5152
return (await QueryAsync(async connection =>
5253
{
5354
var query =
5455
@"insert into ""WorkItems"" (""Title"", ""IsBlocked"", ""DurationInHours"", ""ProjectId"") values " +
5556
@"(@description, @isLocked, @ordinal, @uniqueId) returning ""Id"", ""Title"", ""IsBlocked"", ""DurationInHours"", ""ProjectId""";
5657

57-
return await connection.QueryAsync<WorkItem>(query, new
58+
return await connection.QueryAsync<WorkItem>(new CommandDefinition(query, new
5859
{
5960
description = resource.Title, ordinal = resource.DurationInHours, uniqueId = resource.ProjectId, isLocked = resource.IsBlocked
60-
});
61+
}, cancellationToken: cancellationToken));
6162
})).SingleOrDefault();
6263
}
6364

64-
public Task AddToToManyRelationshipAsync(int primaryId, string relationshipName, ISet<IIdentifiable> secondaryResourceIds)
65+
public Task AddToToManyRelationshipAsync(int primaryId, string relationshipName, ISet<IIdentifiable> secondaryResourceIds, CancellationToken cancellationToken)
6566
{
6667
throw new NotImplementedException();
6768
}
6869

69-
public Task<WorkItem> UpdateAsync(int id, WorkItem resource)
70+
public Task<WorkItem> UpdateAsync(int id, WorkItem resource, CancellationToken cancellationToken)
7071
{
7172
throw new NotImplementedException();
7273
}
7374

74-
public Task SetRelationshipAsync(int primaryId, string relationshipName, object secondaryResourceIds)
75+
public Task SetRelationshipAsync(int primaryId, string relationshipName, object secondaryResourceIds, CancellationToken cancellationToken)
7576
{
7677
throw new NotImplementedException();
7778
}
7879

79-
public async Task DeleteAsync(int id)
80+
public async Task DeleteAsync(int id, CancellationToken cancellationToken)
8081
{
8182
await QueryAsync(async connection =>
82-
await connection.QueryAsync<WorkItem>(@"delete from ""WorkItems"" where ""Id""=@id", new {id}));
83+
await connection.QueryAsync<WorkItem>(new CommandDefinition(@"delete from ""WorkItems"" where ""Id""=@id", new {id}, cancellationToken: cancellationToken)));
8384
}
8485

85-
public Task RemoveFromToManyRelationshipAsync(int primaryId, string relationshipName, ISet<IIdentifiable> secondaryResourceIds)
86+
public Task RemoveFromToManyRelationshipAsync(int primaryId, string relationshipName, ISet<IIdentifiable> secondaryResourceIds, CancellationToken cancellationToken)
8687
{
8788
throw new NotImplementedException();
8889
}

src/Examples/ReportsExample/Controllers/ReportsController.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Threading;
12
using System.Threading.Tasks;
23
using JsonApiDotNetCore.Configuration;
34
using JsonApiDotNetCore.Controllers;
@@ -19,6 +20,9 @@ public ReportsController(
1920
{ }
2021

2122
[HttpGet]
22-
public override async Task<IActionResult> GetAsync() => await base.GetAsync();
23+
public override async Task<IActionResult> GetAsync(CancellationToken cancellationToken)
24+
{
25+
return await base.GetAsync(cancellationToken);
26+
}
2327
}
2428
}

src/Examples/ReportsExample/Services/ReportService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.Linq;
3+
using System.Threading;
34
using System.Threading.Tasks;
45
using JsonApiDotNetCore.Services;
56
using Microsoft.Extensions.Logging;
@@ -16,7 +17,7 @@ public ReportService(ILoggerFactory loggerFactory)
1617
_logger = loggerFactory.CreateLogger<ReportService>();
1718
}
1819

19-
public Task<IReadOnlyCollection<Report>> GetAsync()
20+
public Task<IReadOnlyCollection<Report>> GetAsync(CancellationToken cancellationToken)
2021
{
2122
_logger.LogInformation("GetAsync");
2223

0 commit comments

Comments
 (0)