Skip to content

Commit ca51bc7

Browse files
AsyncOperation
1 parent 95173ef commit ca51bc7

File tree

3 files changed

+74
-141
lines changed

3 files changed

+74
-141
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using System.Collections.Concurrent;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
5+
namespace Microsoft.Azure.Experiments
6+
{
7+
abstract class AsyncOperation : IResourceConfigVisitor<Task<object>>
8+
{
9+
public AsyncOperation(IClient client, CancellationToken cancellationToken)
10+
{
11+
Client = client;
12+
CancellationToken = cancellationToken;
13+
}
14+
15+
public async Task<object> GetOrAddUntyped(IResourceConfig config)
16+
=> await TaskMap.GetOrAdd(
17+
config,
18+
async _ =>
19+
{
20+
var info = await config.Apply(this);
21+
Result.GetOrAddUntyped(config, () => info);
22+
return info;
23+
});
24+
25+
public async Task<Config> GetOrAdd<Config>(IResourceConfig<Config> config)
26+
where Config : class
27+
{
28+
var result = await GetOrAddUntyped(config);
29+
return result as Config;
30+
}
31+
32+
public abstract Task<object> Visit<Config>(ResourceConfig<Config> config) where Config : class;
33+
34+
public abstract Task<object> Visit<Config, ParentConfig>(NestedResourceConfig<Config, ParentConfig> config)
35+
where Config : class
36+
where ParentConfig : class;
37+
38+
public IClient Client { get; }
39+
40+
public CancellationToken CancellationToken { get; }
41+
42+
public State Result { get; } = new State();
43+
44+
ConcurrentDictionary<IResourceConfig, Task<object>> TaskMap { get; }
45+
= new ConcurrentDictionary<IResourceConfig, Task<object>>();
46+
}
47+
}
Lines changed: 10 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using Microsoft.Rest.Azure;
2-
using System.Collections.Concurrent;
32
using System.Linq;
43
using System.Net;
54
using System.Threading;
@@ -10,44 +9,25 @@ namespace Microsoft.Azure.Experiments
109
public static class CurrentState
1110
{
1211
public static async Task<IState> GetState<Config>(
13-
IClient client, IResourceConfig<Config> resourceConfig)
12+
this IResourceConfig<Config> resourceConfig,
13+
IClient client,
14+
CancellationToken cancellationToken)
1415
where Config : class
1516
{
16-
var visitor = new Visitor(client);
17+
var visitor = new Visitor(client, cancellationToken);
1718
await visitor.GetOrAdd(resourceConfig);
1819
return visitor.Result;
1920
}
2021

21-
sealed class Visitor : IResourceConfigVisitor<Task<object>>
22+
sealed class Visitor : AsyncOperation
2223
{
23-
public async Task<object> GetOrAddUntyped(IResourceConfig config)
24-
=> await Map.GetOrAdd(
25-
config,
26-
async _ =>
27-
{
28-
var info = await config.Apply(this);
29-
if (info != null)
30-
{
31-
Result.GetOrAddUntyped(config, () => info);
32-
}
33-
return info;
34-
});
35-
36-
public async Task<Config> GetOrAdd<Config>(IResourceConfig<Config> config)
37-
where Config : class
38-
{
39-
var result = await GetOrAddUntyped(config);
40-
return result as Config;
41-
}
42-
43-
public async Task<object> Visit<Config>(ResourceConfig<Config> config)
44-
where Config : class
24+
public override async Task<object> Visit<Config>(ResourceConfig<Config> config)
4525
{
4626
Config info;
4727
try
4828
{
4929
info = await config.Policy.GetAsync(GetAsyncParams.Create(
50-
Client, config.ResourceGroupName, config.Name, new CancellationToken()));
30+
Client, config.ResourceGroupName, config.Name, CancellationToken));
5131
}
5232
catch (CloudException e) when (e.Response.StatusCode == HttpStatusCode.NotFound)
5333
{
@@ -62,26 +42,17 @@ public async Task<object> Visit<Config>(ResourceConfig<Config> config)
6242
return info;
6343
}
6444

65-
public async Task<object> Visit<Config, ParentConfig>(
45+
public override async Task<object> Visit<Config, ParentConfig>(
6646
NestedResourceConfig<Config, ParentConfig> config)
67-
where Config : class
68-
where ParentConfig : class
6947
{
7048
var parent = await GetOrAdd(config.Parent);
7149
return parent == null ? null : config.Policy.Get(parent);
7250
}
7351

74-
public Visitor(IClient client)
52+
public Visitor(IClient client, CancellationToken cancellationToken)
53+
: base(client, cancellationToken)
7554
{
76-
Client = client;
7755
}
78-
79-
public State Result { get; } = new State();
80-
81-
IClient Client { get; }
82-
83-
ConcurrentDictionary<IResourceConfig, Task<object>> Map { get; }
84-
= new ConcurrentDictionary<IResourceConfig, Task<object>>();
8556
}
8657
}
8758
}
Lines changed: 17 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System.Collections.Concurrent;
2-
using System.Linq;
1+
using System.Linq;
32
using System.Threading;
43
using System.Threading.Tasks;
54

@@ -8,37 +7,21 @@ namespace Microsoft.Azure.Experiments
87
public static class ResourceOperations
98
{
109
public static async Task<IState> CreateAsync<Config>(
11-
this IResourceConfig<Config> config, IClient client, IState current, IState parameters)
10+
this IResourceConfig<Config> config,
11+
IClient client,
12+
IState current,
13+
IState parameters,
14+
CancellationToken cancellationToken)
1215
where Config : class
1316
{
14-
var visitor = new CreateAsyncVisitor(client, current, parameters);
17+
var visitor = new CreateAsyncVisitor(client, current, parameters, cancellationToken);
1518
await visitor.GetOrAdd(config);
1619
return visitor.Result;
1720
}
1821

19-
sealed class CreateAsyncVisitor : IResourceConfigVisitor<Task<object>>
22+
sealed class CreateAsyncVisitor : AsyncOperation
2023
{
21-
public async Task<object> GetOrAddUntyped(IResourceConfig config)
22-
=> await TaskMap.GetOrAdd(
23-
config,
24-
async _ =>
25-
{
26-
var info = await config.Apply(this);
27-
if (info != null)
28-
{
29-
Result.GetOrAddUntyped(config, () => info);
30-
}
31-
return info;
32-
});
33-
34-
public async Task<Config> GetOrAdd<Config>(IResourceConfig<Config> config)
35-
where Config : class
36-
{
37-
var result = await GetOrAddUntyped(config);
38-
return result as Config;
39-
}
40-
41-
public async Task<object> Visit<Config>(ResourceConfig<Config> config) where Config : class
24+
public override async Task<object> Visit<Config>(ResourceConfig<Config> config)
4225
{
4326
var current = Current.GetOrNull(config);
4427
if (current != null)
@@ -52,98 +35,30 @@ public async Task<object> Visit<Config>(ResourceConfig<Config> config) where Con
5235
config.ResourceGroupName,
5336
config.Name,
5437
Parameters.GetOrNull(config),
55-
new CancellationToken()));
38+
CancellationToken));
5639
}
5740

58-
public async Task<object> Visit<Config, ParentConfig>(
41+
public override async Task<object> Visit<Config, ParentConfig>(
5942
NestedResourceConfig<Config, ParentConfig> config)
60-
where Config : class
61-
where ParentConfig : class
6243
{
6344
var parent = await GetOrAdd(config.Parent);
6445
return config.Policy.Get(parent);
6546
}
6647

67-
public CreateAsyncVisitor(IClient client, IState current, IState parameters)
48+
public CreateAsyncVisitor(
49+
IClient client,
50+
IState current,
51+
IState parameters,
52+
CancellationToken cancellationToken)
53+
: base(client, cancellationToken)
6854
{
69-
Client = client;
7055
Current = current;
7156
Parameters = parameters;
7257
}
7358

74-
public State Result { get; } = new State();
75-
76-
IClient Client { get; }
77-
7859
IState Current { get; }
7960

8061
IState Parameters { get; }
81-
82-
ConcurrentDictionary<IResourceConfig, Task<object>> TaskMap { get; }
83-
= new ConcurrentDictionary<IResourceConfig, Task<object>>();
84-
}
85-
}
86-
87-
/*
88-
public sealed class CreateOperation
89-
{
90-
public Func<IClient, IStateSet, Task> CreateAsync { get; }
91-
92-
public IEnumerable<CreateOperation> Dependencies { get; }
93-
94-
public CreateOperation(
95-
Func<IClient, Task> createAsync,
96-
IEnumerable<CreateOperation> dependencies)
97-
{
98-
CreateAsync = createAsync;
99-
Dependencies = dependencies;
100-
}
101-
102-
public static CreateOperation Create<Config>(IState state, IResourceConfig<Config> config)
103-
where Config : class
104-
=> new Visitor(state).Get(config);
105-
106-
sealed class Visitor : IResourceConfigVisitor<CreateOperation>
107-
{
108-
public CreateOperation Get(IResourceConfig config)
109-
=> Map.GetOrAdd(config, _ => config.Apply(this));
110-
111-
public CreateOperation Visit<Config>(ResourceConfig<Config> config) where Config : class
112-
{
113-
var info = State.Get(config);
114-
return info == null
115-
? new CreateOperation(
116-
async (client, state) =>
117-
{
118-
var p = config.CreateConfig(client.Context.SubscriptionId);
119-
var i = await config.Policy.CreateOrUpdateAsync(new CreateOrUpdateAsyncParams<IClient, Config>(
120-
client,
121-
config.ResourceGroupName,
122-
config.Name,
123-
p,
124-
new CancellationToken()));
125-
state.Set(config, i);
126-
},
127-
config.Dependencies.Select(d => Get(d)).Where(d => d != null))
128-
: null;
129-
}
130-
131-
public CreateOperation Visit<Config, ParentConfig>(
132-
NestedResourceConfig<Config, ParentConfig> config)
133-
where Config : class
134-
where ParentConfig : class
135-
=> Get(config.Parent);
136-
137-
public Visitor(IStateGet state)
138-
{
139-
State = state;
140-
}
141-
142-
IStateGet State { get; }
143-
144-
ConcurrentDictionary<IResourceConfig, CreateOperation> Map { get; }
145-
= new ConcurrentDictionary<IResourceConfig, CreateOperation>();
14662
}
14763
}
148-
*/
14964
}

0 commit comments

Comments
 (0)