Skip to content

Commit dffa144

Browse files
committed
Merged changes from master
2 parents 9debae4 + 11eeb15 commit dffa144

14 files changed

Lines changed: 1559 additions & 4 deletions
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// --------------------------------------------------------------------------------------------------------------------
2+
// <copyright file="INetworkRequestManager.cs" company="MADE Apps">
3+
// Copyright (c) MADE Apps.
4+
// </copyright>
5+
// <summary>
6+
// Defines an interface for a network request manager.
7+
// </summary>
8+
// --------------------------------------------------------------------------------------------------------------------
9+
10+
namespace MADE.App.Networking
11+
{
12+
using System;
13+
using System.Collections.Concurrent;
14+
15+
using MADE.App.Networking.Requests;
16+
17+
/// <summary>
18+
/// Defines an interface for a network request manager.
19+
/// </summary>
20+
public interface INetworkRequestManager
21+
{
22+
/// <summary>
23+
/// Gets the current queue of network requests.
24+
/// </summary>
25+
ConcurrentDictionary<string, NetworkRequestCallback> CurrentQueue { get; }
26+
27+
/// <summary>
28+
/// Starts the manager processing the queue of network requests at a default time period of 1 minute.
29+
/// </summary>
30+
void Start();
31+
32+
/// <summary>
33+
/// Starts the manager processing the queue of network requests.
34+
/// </summary>
35+
/// <param name="processPeriod">
36+
/// The time period between each process of the queue.
37+
/// </param>
38+
void Start(TimeSpan processPeriod);
39+
40+
/// <summary>
41+
/// Stops the processing of the network manager queues.
42+
/// </summary>
43+
void Stop();
44+
45+
/// <summary>
46+
/// Adds or updates a network request in the queue.
47+
/// </summary>
48+
/// <typeparam name="TRequest">
49+
/// The type of network request.
50+
/// </typeparam>
51+
/// <typeparam name="TResponse">
52+
/// The expected response type.
53+
/// </typeparam>
54+
/// <param name="request">
55+
/// The network request to execute.
56+
/// </param>
57+
/// <param name="successCallback">
58+
/// The action to execute when receiving a successful response.
59+
/// </param>
60+
void AddOrUpdate<TRequest, TResponse>(TRequest request, Action<TResponse> successCallback)
61+
where TRequest : NetworkRequest;
62+
63+
/// <summary>
64+
/// Adds or updates a network request in the queue.
65+
/// </summary>
66+
/// <typeparam name="TRequest">
67+
/// The type of network request.
68+
/// </typeparam>
69+
/// <typeparam name="TResponse">
70+
/// The expected response type.
71+
/// </typeparam>
72+
/// <typeparam name="TErrorResponse">
73+
/// The expected error response type.
74+
/// </typeparam>
75+
/// <param name="request">
76+
/// The network request to execute.
77+
/// </param>
78+
/// <param name="successCallback">
79+
/// The action to execute when receiving a successful response.
80+
/// </param>
81+
/// <param name="errorCallback">
82+
/// The action to execute when receiving an error response.
83+
/// </param>
84+
void AddOrUpdate<TRequest, TResponse, TErrorResponse>(
85+
TRequest request,
86+
Action<TResponse> successCallback,
87+
Action<TErrorResponse> errorCallback)
88+
where TRequest : NetworkRequest;
89+
90+
/// <summary>
91+
/// Processes the current queue of network requests.
92+
/// </summary>
93+
void ProcessCurrentQueue();
94+
}
95+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFrameworks>netstandard2.0;uap10.0.16299</TargetFrameworks>
5+
</PropertyGroup>
6+
7+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
8+
<DocumentationFile>bin\Debug\netstandard2.0\MADE.App.Networking.xml</DocumentationFile>
9+
</PropertyGroup>
10+
11+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
12+
<DocumentationFile>bin\Release\netstandard2.0\MADE.App.Networking.xml</DocumentationFile>
13+
</PropertyGroup>
14+
15+
<ItemGroup>
16+
<Compile Remove="api\**" />
17+
<Compile Remove="articles\**" />
18+
<Compile Remove="_site\**" />
19+
<EmbeddedResource Remove="api\**" />
20+
<EmbeddedResource Remove="articles\**" />
21+
<EmbeddedResource Remove="_site\**" />
22+
<None Remove="api\**" />
23+
<None Remove="articles\**" />
24+
<None Remove="_site\**" />
25+
</ItemGroup>
26+
27+
<PropertyGroup>
28+
<LogFile>Docfx-$(TargetFramework).log</LogFile>
29+
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
30+
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
31+
<Version>1.0.0.0</Version>
32+
<Authors>MADE Apps</Authors>
33+
<Company>MADE Apps</Company>
34+
<Product>MADE App Networking Library</Product>
35+
<Description>Making App Development Easier with a collection of easy to use APIs for working with networking requests for .NET projects across Windows, Android, and iOS.</Description>
36+
<Copyright>Copyright (C) MADE Apps. All rights reserved.</Copyright>
37+
<PackageLicenseUrl>https://github.com/MADE-Apps/MADE-App-Components/blob/master/LICENSE</PackageLicenseUrl>
38+
<PackageProjectUrl>https://github.com/MADE-Apps/MADE-App-Components</PackageProjectUrl>
39+
<RepositoryUrl>https://github.com/MADE-Apps/MADE-App-Components</RepositoryUrl>
40+
<RepositoryType>git</RepositoryType>
41+
<PackageIconUrl>https://pbs.twimg.com/profile_images/927154020422160385/6HSRU36P_400x400.jpg</PackageIconUrl>
42+
<PackageTags>MADE App Development View Networking HttpClient Windows Android iOS Xamarin</PackageTags>
43+
</PropertyGroup>
44+
45+
<ItemGroup>
46+
<None Remove=".gitignore" />
47+
<None Remove="docfx.json" />
48+
<None Remove="index.md" />
49+
<None Remove="log.txt" />
50+
<None Remove="toc.yml" />
51+
<None Remove="Docfx-*.log" />
52+
</ItemGroup>
53+
54+
<ItemGroup>
55+
<PackageReference Include="docfx.console" Version="2.36.0" PrivateAssets="All" />
56+
<PackageReference Include="MSBuild.Sdk.Extras" Version="1.5.4" PrivateAssets="All" />
57+
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
58+
</ItemGroup>
59+
60+
<ItemGroup Condition=" '$(TargetFramework)' == 'uap10.0.16299' ">
61+
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="6.1.4" />
62+
</ItemGroup>
63+
64+
<ItemGroup>
65+
<ProjectReference Include="..\MADE.App\MADE.App.csproj" />
66+
</ItemGroup>
67+
68+
<Import Project="$(MSBuildSDKExtrasTargets)" Condition="Exists('$(MSBuildSDKExtrasTargets)')" />
69+
70+
</Project>
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
// --------------------------------------------------------------------------------------------------------------------
2+
// <copyright file="NetworkRequestManager.cs" company="MADE Apps">
3+
// Copyright (c) MADE Apps.
4+
// </copyright>
5+
// <summary>
6+
// Defines a manager for executing queued network requests.
7+
// </summary>
8+
// --------------------------------------------------------------------------------------------------------------------
9+
10+
namespace MADE.App.Networking
11+
{
12+
using System;
13+
using System.Collections.Concurrent;
14+
using System.Collections.Generic;
15+
using System.Linq;
16+
using System.Threading;
17+
using System.Threading.Tasks;
18+
19+
using MADE.App.Networking.Requests;
20+
21+
/// <summary>
22+
/// Defines a manager for executing queued network requests.
23+
/// </summary>
24+
public sealed class NetworkRequestManager : INetworkRequestManager
25+
{
26+
private Timer processTimer;
27+
28+
private bool isProcessingRequests;
29+
30+
/// <summary>
31+
/// Initializes a new instance of the <see cref="NetworkRequestManager"/> class.
32+
/// </summary>
33+
public NetworkRequestManager()
34+
{
35+
this.CurrentQueue = new ConcurrentDictionary<string, NetworkRequestCallback>();
36+
}
37+
38+
/// <summary>
39+
/// Gets the current queue of network requests.
40+
/// </summary>
41+
public ConcurrentDictionary<string, NetworkRequestCallback> CurrentQueue { get; }
42+
43+
/// <summary>
44+
/// Starts the manager processing the queue of network requests at a default time period of 1 minute.
45+
/// </summary>
46+
public void Start()
47+
{
48+
this.Start(TimeSpan.FromMinutes(1));
49+
}
50+
51+
/// <summary>
52+
/// Starts the manager processing the queue of network requests.
53+
/// </summary>
54+
/// <param name="processPeriod">
55+
/// The time period between each process of the queue.
56+
/// </param>
57+
public void Start(TimeSpan processPeriod)
58+
{
59+
if (this.processTimer == null)
60+
{
61+
this.processTimer = new Timer(
62+
state => this.ProcessCurrentQueue(),
63+
null,
64+
TimeSpan.FromMinutes(0),
65+
processPeriod);
66+
}
67+
else
68+
{
69+
this.processTimer.Change(TimeSpan.FromMinutes(0), processPeriod);
70+
}
71+
}
72+
73+
/// <summary>
74+
/// Stops the processing of the network manager queues.
75+
/// </summary>
76+
public void Stop()
77+
{
78+
this.processTimer?.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
79+
}
80+
81+
/// <summary>
82+
/// Processes the current queue of network requests.
83+
/// </summary>
84+
public void ProcessCurrentQueue()
85+
{
86+
if (this.isProcessingRequests)
87+
{
88+
return;
89+
}
90+
91+
if (this.CurrentQueue.Count > 0)
92+
{
93+
return;
94+
}
95+
96+
this.isProcessingRequests = true;
97+
98+
try
99+
{
100+
CancellationTokenSource cts = new CancellationTokenSource();
101+
List<Task> requestTasks = new List<Task>();
102+
List<NetworkRequestCallback> requestCallbacks = new List<NetworkRequestCallback>();
103+
104+
while (this.CurrentQueue.Count > 0)
105+
{
106+
if (this.CurrentQueue.TryRemove(
107+
this.CurrentQueue.FirstOrDefault().Key,
108+
out NetworkRequestCallback request))
109+
{
110+
requestCallbacks.Add(request);
111+
}
112+
}
113+
114+
foreach (NetworkRequestCallback container in requestCallbacks)
115+
{
116+
requestTasks.Add(ExecuteRequestsAsync(this.CurrentQueue, container, cts));
117+
}
118+
}
119+
finally
120+
{
121+
this.isProcessingRequests = false;
122+
}
123+
}
124+
125+
/// <summary>
126+
/// Adds or updates a network request in the queue.
127+
/// </summary>
128+
/// <typeparam name="TRequest">
129+
/// The type of network request.
130+
/// </typeparam>
131+
/// <typeparam name="TResponse">
132+
/// The expected response type.
133+
/// </typeparam>
134+
/// <param name="request">
135+
/// The network request to execute.
136+
/// </param>
137+
/// <param name="successCallback">
138+
/// The action to execute when receiving a successful response.
139+
/// </param>
140+
public void AddOrUpdate<TRequest, TResponse>(TRequest request, Action<TResponse> successCallback)
141+
where TRequest : NetworkRequest
142+
{
143+
this.AddOrUpdate<TRequest, TResponse, Exception>(request, successCallback, null);
144+
}
145+
146+
/// <summary>
147+
/// Adds or updates a network request in the queue.
148+
/// </summary>
149+
/// <typeparam name="TRequest">
150+
/// The type of network request.
151+
/// </typeparam>
152+
/// <typeparam name="TResponse">
153+
/// The expected response type.
154+
/// </typeparam>
155+
/// <typeparam name="TErrorResponse">
156+
/// The expected error response type.
157+
/// </typeparam>
158+
/// <param name="request">
159+
/// The network request to execute.
160+
/// </param>
161+
/// <param name="successCallback">
162+
/// The action to execute when receiving a successful response.
163+
/// </param>
164+
/// <param name="errorCallback">
165+
/// The action to execute when receiving an error response.
166+
/// </param>
167+
public void AddOrUpdate<TRequest, TResponse, TErrorResponse>(
168+
TRequest request,
169+
Action<TResponse> successCallback,
170+
Action<TErrorResponse> errorCallback)
171+
where TRequest : NetworkRequest
172+
{
173+
WeakReferenceCallback weakSuccessCallback = new WeakReferenceCallback(successCallback, typeof(TResponse));
174+
WeakReferenceCallback weakErrorCallback = new WeakReferenceCallback(errorCallback, typeof(TErrorResponse));
175+
NetworkRequestCallback requestCallback = new NetworkRequestCallback(
176+
request,
177+
weakSuccessCallback,
178+
weakErrorCallback);
179+
180+
this.CurrentQueue.AddOrUpdate(
181+
request.Identifier.ToString(),
182+
requestCallback,
183+
(s, callback) => requestCallback);
184+
}
185+
186+
private static async Task ExecuteRequestsAsync(
187+
ConcurrentDictionary<string, NetworkRequestCallback> queue,
188+
NetworkRequestCallback requestCallback,
189+
CancellationTokenSource cts)
190+
{
191+
if (cts.IsCancellationRequested)
192+
{
193+
queue.AddOrUpdate(
194+
requestCallback.Request.Identifier.ToString(),
195+
requestCallback,
196+
(s, callback) => requestCallback);
197+
198+
return;
199+
}
200+
201+
NetworkRequest request = requestCallback.Request;
202+
WeakReferenceCallback successCallback = requestCallback.SuccessCallback;
203+
WeakReferenceCallback errorCallback = requestCallback.ErrorCallback;
204+
205+
try
206+
{
207+
object response = await request.ExecuteAsync(successCallback.Type);
208+
successCallback.Invoke(response);
209+
}
210+
catch (Exception ex)
211+
{
212+
successCallback.Invoke(Activator.CreateInstance(successCallback.Type));
213+
errorCallback.Invoke(ex);
214+
}
215+
}
216+
}
217+
}

0 commit comments

Comments
 (0)