Skip to content

Commit d21672e

Browse files
committed
修复一个请求 timeout 导致后续全部 timeout 的问题
1 parent c512471 commit d21672e

File tree

6 files changed

+36
-45
lines changed

6 files changed

+36
-45
lines changed

package.props

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
<Project>
22

33
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
<LangVersion>latest</LangVersion>
46
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
57
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
68
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
7-
<Version>5.0.1-beta6</Version>
8-
<FileVersion>5.0.1.6</FileVersion>
9+
<Version>5.0.1-beta7</Version>
10+
<FileVersion>5.0.1.7</FileVersion>
911
<Authors>[email protected];</Authors>
1012
<Copyright>Copyright 2018 Lewis Zou</Copyright>
1113
<Description>DotnetSpider, a .NET Standard web crawling library. It is lightweight, efficient and fast high-level web crawling &amp; scraping framework</Description>
@@ -16,7 +18,7 @@
1618
</PropertyGroup>
1719

1820
<ItemGroup>
19-
<None Include="..\..\LICENSE.txt" Pack="true" PackagePath="LICENSE.txt" />
21+
<None Include="..\..\LICENSE.txt" Pack="true" PackagePath="LICENSE.txt"/>
2022
</ItemGroup>
2123

2224
</Project>

src/DotnetSpider.Portal/Startup.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
120120
{
121121
endpoints.MapHealthChecks("/health");
122122
endpoints.MapControllerRoute(
123-
name: "default",
124-
pattern: "{controller=Home}/{action=Index}/{id?}");
123+
"default",
124+
"{controller=Home}/{action=Index}/{id?}");
125125
});
126126

127127
SeedData.InitializeAsync(new PortalOptions(Configuration), app.ApplicationServices).GetAwaiter()

src/DotnetSpider.Portal/Views/Shared/_Layout.cshtml

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,6 @@
7171
</environment>
7272
@await Html.PartialAsync("Pagination")
7373
@await Html.PartialAsync("Select2")
74-
@RenderSection("Scripts", required: false)
74+
@RenderSection("Scripts", false)
7575
</body>
7676
</html>

src/DotnetSpider.RabbitMQ/RabbitMQMessageQueue.cs

+9-9
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public RabbitMQMessageQueue(IOptions<RabbitMQOptions> options, ILoggerFactory lo
3838
_logger.LogTrace("Creating RabbitMQ publish channel");
3939

4040
_publishChannel = _connection.CreateModel();
41-
_publishChannel.ExchangeDeclare(exchange: _options.Exchange, type: "direct", durable: true);
41+
_publishChannel.ExchangeDeclare(_options.Exchange, "direct", true);
4242
}
4343

4444
private IConnectionFactory CreateConnectionFactory()
@@ -122,12 +122,12 @@ public Task ConsumeAsync(AsyncMessageConsumer<byte[]> consumer,
122122

123123
var channel = _connection.CreateModel();
124124
var basicConsumer = new AsyncEventingBasicConsumer(channel);
125-
channel.QueueDeclare(queue: consumer.Queue,
126-
durable: true,
127-
exclusive: false,
128-
autoDelete: true,
129-
arguments: null);
130-
channel.QueueBind(queue: consumer.Queue, _options.Exchange, routingKey: consumer.Queue);
125+
channel.QueueDeclare(consumer.Queue,
126+
true,
127+
false,
128+
true,
129+
null);
130+
channel.QueueBind(consumer.Queue, _options.Exchange, consumer.Queue);
131131
basicConsumer.Received += async (model, ea) =>
132132
{
133133
try
@@ -136,15 +136,15 @@ public Task ConsumeAsync(AsyncMessageConsumer<byte[]> consumer,
136136
}
137137
finally
138138
{
139-
channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
139+
channel.BasicAck(ea.DeliveryTag, false);
140140
}
141141
};
142142
consumer.OnClosing += x =>
143143
{
144144
channel.Close();
145145
};
146146
//7. 启动消费者
147-
channel.BasicConsume(queue: consumer.Queue, autoAck: false, consumer: basicConsumer);
147+
channel.BasicConsume(consumer.Queue, false, basicConsumer);
148148

149149
return Task.CompletedTask;
150150
}

src/DotnetSpider/Infrastructure/RequestedQueue.cs

+17-28
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Runtime.CompilerServices;
2+
using System.Collections.Concurrent;
3+
using System.Threading;
44
using System.Threading.Tasks;
55
using DotnetSpider.Http;
66
using HWT;
@@ -9,66 +9,55 @@ namespace DotnetSpider.Infrastructure
99
{
1010
public class RequestedQueue : IDisposable
1111
{
12-
private readonly Dictionary<string, Request> _dict;
13-
12+
private readonly ConcurrentDictionary<string, Request> _dict;
1413
private readonly HashedWheelTimer _timer;
15-
16-
private readonly List<Request> _queue;
14+
private ConcurrentBag<Request> _queue;
1715

1816
public RequestedQueue()
1917
{
20-
_dict = new Dictionary<string, Request>();
21-
_queue = new List<Request>();
18+
_dict = new ConcurrentDictionary<string, Request>();
19+
_queue = new ConcurrentBag<Request>();
2220
_timer = new HashedWheelTimer(TimeSpan.FromSeconds(1)
23-
, ticksPerWheel: 100000
24-
, maxPendingTimeouts: 0);
21+
, 100000);
2522
}
2623

2724
public int Count => _dict.Count;
2825

29-
[MethodImpl(MethodImplOptions.Synchronized)]
3026
public bool Enqueue(Request request)
3127
{
3228
if (request.Timeout <= 2000)
3329
{
3430
throw new SpiderException("Timeout should not less than 2000 milliseconds");
3531
}
3632

37-
if (!_dict.ContainsKey(request.Hash))
33+
if (!_dict.TryAdd(request.Hash, request))
3834
{
39-
_dict.Add(request.Hash, request);
40-
_timer.NewTimeout(new TimeoutTask(this, request.Hash),
41-
TimeSpan.FromMilliseconds(request.Timeout));
42-
return true;
35+
return false;
4336
}
4437

45-
return false;
38+
_timer.NewTimeout(new TimeoutTask(this, request.Hash),
39+
TimeSpan.FromMilliseconds(request.Timeout));
40+
return true;
4641
}
4742

48-
[MethodImpl(MethodImplOptions.Synchronized)]
43+
4944
public Request Dequeue(string hash)
5045
{
51-
var request = _dict[hash];
52-
_dict.Remove(hash);
53-
return request;
46+
return _dict.TryRemove(hash, out var request) ? request : null;
5447
}
5548

56-
[MethodImpl(MethodImplOptions.Synchronized)]
5749
public Request[] GetAllTimeoutList()
5850
{
5951
var data = _queue.ToArray();
60-
_queue.Clear();
52+
Interlocked.Exchange(ref _queue, new ConcurrentBag<Request>());
6153
return data;
6254
}
6355

64-
[MethodImpl(MethodImplOptions.Synchronized)]
6556
private void Timeout(string hash)
6657
{
67-
if (_dict.ContainsKey(hash))
58+
if (_dict.TryRemove(hash, out var request))
6859
{
69-
var request = _dict[hash];
7060
_queue.Add(request);
71-
_dict.Remove(hash);
7261
}
7362
}
7463

@@ -93,7 +82,7 @@ public Task RunAsync(ITimeout timeout)
9382
public void Dispose()
9483
{
9584
_dict.Clear();
96-
_queue.Clear();
85+
Interlocked.Exchange(ref _queue, new ConcurrentBag<Request>());
9786
_timer.Dispose();
9887
}
9988
}

src/DotnetSpider/Proxy/ProxyService.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ public ProxyEntry(Uri uri)
3030
private readonly IProxyValidator _proxyValidator;
3131

3232
private readonly HashedWheelTimer _timer = new HashedWheelTimer(TimeSpan.FromSeconds(1)
33-
, ticksPerWheel: 100000
34-
, maxPendingTimeouts: 0);
33+
, 100000
34+
, 0);
3535

3636
public ProxyService(IProxyValidator proxyValidator)
3737
{

0 commit comments

Comments
 (0)