Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
CAP
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
tsai
CAP
Commits
75f5a81f
Commit
75f5a81f
authored
Jul 08, 2017
by
Savorboard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Repair when subscribe to different Group,can't receiving message bug.
parent
dffa03c3
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
86 additions
and
57 deletions
+86
-57
CAP.Options.cs
src/DotNetCore.CAP/CAP.Options.cs
+18
-4
IConsumerHandler.Default.cs
src/DotNetCore.CAP/IConsumerHandler.Default.cs
+18
-22
IConsumerInvoker.Default.cs
src/DotNetCore.CAP/Internal/IConsumerInvoker.Default.cs
+13
-14
MethodMatcherCache.cs
src/DotNetCore.CAP/Internal/MethodMatcherCache.cs
+29
-8
IJob.CapJob.cs
src/DotNetCore.CAP/Job/IJob.CapJob.cs
+8
-9
No files found.
src/DotNetCore.CAP/CAP.Options.cs
View file @
75f5a81f
using
DotNetCore.CAP.Job
;
namespace
DotNetCore.CAP
namespace
DotNetCore.CAP
{
/// <summary>
/// Represents all the options you can use to configure the system.
/// </summary>
public
class
CapOptions
{
/// <summary>
/// Default value for polling delay timeout, in seconds.
/// </summary>
public
const
int
DefaultPollingDelay
=
8
;
/// <summary>
/// Default value for CAP job.
/// </summary>
public
const
string
DefaultCronExp
=
"* * * * *"
;
public
CapOptions
()
{
CronExp
=
DefaultCronExp
;
PollingDelay
=
DefaultPollingDelay
;
}
/// <summary>
/// Corn expression for configuring retry cron job. Default is 1 min.
/// </summary>
public
string
CronExp
{
get
;
set
;
}
=
Cron
.
Minutely
();
public
string
CronExp
{
get
;
set
;
}
/// <summary>
/// Productor job polling delay time. Default is 8 sec.
...
...
src/DotNetCore.CAP/IConsumerHandler.Default.cs
View file @
75f5a81f
...
...
@@ -23,7 +23,7 @@ namespace DotNetCore.CAP
private
readonly
CapOptions
_options
;
private
readonly
CancellationTokenSource
_cts
;
public
event
EventHandler
<
CapMessage
>
MessageReceieved
;
public
event
EventHandler
<
MessageContext
>
MessageReceieved
;
private
Task
_compositeTask
;
private
bool
_disposed
;
...
...
@@ -46,15 +46,14 @@ namespace DotNetCore.CAP
_cts
=
new
CancellationTokenSource
();
}
protected
virtual
void
OnMessageReceieved
(
CapMessage
message
)
protected
virtual
void
OnMessageReceieved
(
MessageContext
message
)
{
MessageReceieved
?.
Invoke
(
this
,
message
);
}
public
void
Start
()
{
var
matchs
=
_selector
.
GetCandidatesMethods
(
_serviceProvider
);
var
groupingMatchs
=
matchs
.
GroupBy
(
x
=>
x
.
Value
.
Attribute
.
Group
);
var
groupingMatchs
=
_selector
.
GetCandidatesMethodsOfGroupNameGrouped
(
_serviceProvider
);
foreach
(
var
matchGroup
in
groupingMatchs
)
{
...
...
@@ -64,9 +63,9 @@ namespace DotNetCore.CAP
{
client
.
MessageReceieved
+=
OnMessageReceieved
;
foreach
(
var
item
in
matchGroup
)
foreach
(
var
item
in
matchGroup
.
Value
)
{
client
.
Subscribe
(
item
.
Key
);
client
.
Subscribe
(
item
.
Attribute
.
Name
);
}
client
.
Listening
(
TimeSpan
.
FromSeconds
(
1
));
...
...
@@ -76,7 +75,7 @@ namespace DotNetCore.CAP
_compositeTask
=
Task
.
CompletedTask
;
}
public
virtual
void
OnMessageReceieved
(
object
sender
,
Message
Base
message
)
public
virtual
void
OnMessageReceieved
(
object
sender
,
Message
Context
message
)
{
_logger
.
EnqueuingReceivedMessage
(
message
.
KeyName
,
message
.
Content
);
...
...
@@ -88,27 +87,24 @@ namespace DotNetCore.CAP
var
capMessage
=
new
CapReceivedMessage
(
message
)
{
StatusName
=
StatusName
.
Enqueued
,
Added
=
DateTime
.
Now
};
messageStore
.
StoreReceivedMessageAsync
(
capMessage
).
Wait
();
ConsumerExecutorDescriptor
executeDescriptor
=
null
;
try
{
executeDescriptor
=
_selector
.
GetTopicExector
(
message
.
KeyName
);
var
consumerContext
=
new
ConsumerContext
(
executeDescriptor
,
message
);
var
invoker
=
_consumerInvokerFactory
.
CreateInvoker
(
consumerContext
);
invoker
.
InvokeAsync
();
messageStore
.
ChangeReceivedMessageStateAsync
(
capMessage
,
StatusName
.
Succeeded
).
Wait
();
var
executeDescriptorGroup
=
_selector
.
GetTopicExector
(
message
.
KeyName
);
if
(
executeDescriptorGroup
.
ContainsKey
(
message
.
Group
))
{
messageStore
.
ChangeReceivedMessageStateAsync
(
capMessage
,
StatusName
.
Processing
).
Wait
();
// If there are multiple consumers in the same group, we will take the first
var
executeDescriptor
=
executeDescriptorGroup
[
message
.
Group
][
0
];
var
consumerContext
=
new
ConsumerContext
(
executeDescriptor
,
message
);
_consumerInvokerFactory
.
CreateInvoker
(
consumerContext
).
InvokeAsync
();
messageStore
.
ChangeReceivedMessageStateAsync
(
capMessage
,
StatusName
.
Succeeded
).
Wait
();
}
}
catch
(
Exception
ex
)
{
_logger
.
ConsumerMethodExecutingFailed
(
executeDescriptor
?.
MethodInfo
.
Name
,
ex
);
_logger
.
ConsumerMethodExecutingFailed
(
$"Group:
{
message
.
Group
}
, Topic:
{
message
.
KeyName
}
"
,
ex
);
}
}
}
...
...
@@ -126,7 +122,7 @@ namespace DotNetCore.CAP
try
{
_compositeTask
.
Wait
((
int
)
TimeSpan
.
FromSeconds
(
60
).
TotalMilliseconds
);
_compositeTask
.
Wait
((
int
)
TimeSpan
.
FromSeconds
(
60
).
TotalMilliseconds
);
}
catch
(
AggregateException
ex
)
{
...
...
src/DotNetCore.CAP/Internal/IConsumerInvoker.Default.cs
View file @
75f5a81f
...
...
@@ -9,11 +9,10 @@ namespace DotNetCore.CAP.Internal
{
public
class
DefaultConsumerInvoker
:
IConsumerInvoker
{
protected
readonly
ILogger
Logger
;
protected
readonly
IServiceProvider
ServiceProvider
;
protected
readonly
ConsumerContext
ConsumerContext
;
private
readonly
ILogger
_logger
;
private
readonly
IServiceProvider
_serviceProvider
;
private
readonly
IModelBinder
_modelBinder
;
private
readonly
ConsumerContext
_consumerContext
;
private
readonly
ObjectMethodExecutor
_executor
;
public
DefaultConsumerInvoker
(
ILogger
logger
,
...
...
@@ -22,24 +21,24 @@ namespace DotNetCore.CAP.Internal
ConsumerContext
consumerContext
)
{
_modelBinder
=
modelBinder
;
_
executor
=
ObjectMethodExecutor
.
Create
(
ConsumerContext
.
ConsumerDescriptor
.
MethodInfo
,
ConsumerContext
.
ConsumerDescriptor
.
ImplTypeInfo
);
_
serviceProvider
=
serviceProvider
;
_logger
=
logger
??
throw
new
ArgumentNullException
(
nameof
(
logger
)
);
Logger
=
logger
??
throw
new
ArgumentNullException
(
nameof
(
logger
));
ServiceProvider
=
serviceProvider
;
ConsumerContext
=
consumerContext
??
throw
new
ArgumentNullException
(
nameof
(
consumerContext
)
);
_consumerContext
=
consumerContext
??
throw
new
ArgumentNullException
(
nameof
(
consumerContext
));
_executor
=
ObjectMethodExecutor
.
Create
(
_consumerContext
.
ConsumerDescriptor
.
MethodInfo
,
_consumerContext
.
ConsumerDescriptor
.
ImplTypeInfo
);
}
public
Task
InvokeAsync
()
{
using
(
L
ogger
.
BeginScope
(
"consumer invoker begin"
))
using
(
_l
ogger
.
BeginScope
(
"consumer invoker begin"
))
{
Logger
.
LogDebug
(
"Executing consumer Topic: {0}"
,
C
onsumerContext
.
ConsumerDescriptor
.
MethodInfo
.
Name
);
_logger
.
LogDebug
(
"Executing consumer Topic: {0}"
,
_c
onsumerContext
.
ConsumerDescriptor
.
MethodInfo
.
Name
);
var
obj
=
ActivatorUtilities
.
GetServiceOrCreateInstance
(
S
erviceProvider
,
C
onsumerContext
.
ConsumerDescriptor
.
ImplTypeInfo
.
AsType
());
var
obj
=
ActivatorUtilities
.
GetServiceOrCreateInstance
(
_s
erviceProvider
,
_c
onsumerContext
.
ConsumerDescriptor
.
ImplTypeInfo
.
AsType
());
var
value
=
C
onsumerContext
.
DeliverMessage
.
Content
;
var
value
=
_c
onsumerContext
.
DeliverMessage
.
Content
;
if
(
_executor
.
MethodParameters
.
Length
>
0
)
{
...
...
src/DotNetCore.CAP/Internal/MethodMatcherCache.cs
View file @
75f5a81f
using
System
;
using
System.Linq
;
using
System.Collections.Concurrent
;
using
System.Collections.Generic
;
using
DotNetCore.CAP.Abstractions
;
namespace
DotNetCore.CAP.Internal
...
...
@@ -8,35 +10,54 @@ namespace DotNetCore.CAP.Internal
{
private
readonly
IConsumerServiceSelector
_selector
;
private
ConcurrentDictionary
<
string
,
IList
<
ConsumerExecutorDescriptor
>>
Entries
{
get
;
}
public
MethodMatcherCache
(
IConsumerServiceSelector
selector
)
{
_selector
=
selector
;
Entries
=
new
ConcurrentDictionary
<
string
,
IList
<
ConsumerExecutorDescriptor
>>();
}
public
ConcurrentDictionary
<
string
,
ConsumerExecutorDescriptor
>
GetCandidatesMethods
(
IServiceProvider
provider
)
/// <summary>
/// Get a dictionary of candidates.In the dictionary,
/// the Key is the CAPSubscribeAttribute Group, the Value for the current Group of candidates
/// </summary>
/// <param name="provider"><see cref="IServiceProvider"/></param>
public
ConcurrentDictionary
<
string
,
IList
<
ConsumerExecutorDescriptor
>>
GetCandidatesMethodsOfGroupNameGrouped
(
IServiceProvider
provider
)
{
if
(
Entries
.
Count
!=
0
)
return
Entries
;
var
executorCollection
=
_selector
.
SelectCandidates
(
provider
);
foreach
(
var
item
in
executorCollection
)
var
groupedCandidates
=
executorCollection
.
GroupBy
(
x
=>
x
.
Attribute
.
Group
);
foreach
(
var
item
in
groupedCandidates
)
{
Entries
.
GetOrAdd
(
item
.
Attribute
.
Name
,
item
);
Entries
.
TryAdd
(
item
.
Key
,
item
.
ToList
()
);
}
return
Entries
;
}
public
ConsumerExecutorDescriptor
GetTopicExector
(
string
topicName
)
/// <summary>
/// Get a dictionary of specify topic candidates.
/// The Key is Group name, the value is specify topic candidates.
/// </summary>
/// <param name="topicName">message topic name</param>
public
IDictionary
<
string
,
IList
<
ConsumerExecutorDescriptor
>>
GetTopicExector
(
string
topicName
)
{
if
(
Entries
==
null
)
{
throw
new
ArgumentNullException
(
nameof
(
Entries
));
}
return
Entries
[
topicName
];
var
dic
=
new
Dictionary
<
string
,
IList
<
ConsumerExecutorDescriptor
>>();
foreach
(
var
item
in
Entries
)
{
var
topicCandidates
=
item
.
Value
.
Where
(
x
=>
x
.
Attribute
.
Name
==
topicName
);
dic
.
Add
(
item
.
Key
,
topicCandidates
.
ToList
());
}
return
dic
;
}
public
ConcurrentDictionary
<
string
,
ConsumerExecutorDescriptor
>
Entries
{
get
;
}
=
new
ConcurrentDictionary
<
string
,
ConsumerExecutorDescriptor
>();
}
}
\ No newline at end of file
src/DotNetCore.CAP/Job/IJob.CapJob.cs
View file @
75f5a81f
...
...
@@ -32,26 +32,25 @@ namespace DotNetCore.CAP.Job
public
async
Task
ExecuteAsync
()
{
var
matchs
=
_selector
.
GetCandidatesMethods
(
_serviceProvider
);
var
groupedCandidates
=
_selector
.
GetCandidatesMethodsOfGroupNameGrouped
(
_serviceProvider
);
using
(
var
scope
=
_serviceProvider
.
CreateScope
())
{
var
provider
=
scope
.
ServiceProvider
;
var
messageStore
=
provider
.
GetService
<
ICapMessageStore
>();
var
messageStore
=
provider
.
GetService
<
ICapMessageStore
>();
var
nextReceivedMessage
=
await
messageStore
.
GetNextReceivedMessageToBeExcuted
();
if
(
nextReceivedMessage
!=
null
)
if
(
nextReceivedMessage
!=
null
&&
groupedCandidates
.
ContainsKey
(
nextReceivedMessage
.
Group
)
)
{
try
{
var
executeDescriptor
=
matchs
[
nextReceivedMessage
.
KeyName
];
var
consumerContext
=
new
ConsumerContext
(
executeDescriptor
,
nextReceivedMessage
);
var
invoker
=
_consumerInvokerFactory
.
CreateInvoker
(
consumerContext
);
await
messageStore
.
ChangeReceivedMessageStateAsync
(
nextReceivedMessage
,
StatusName
.
Processing
);
// If there are multiple consumers in the same group, we will take the first
var
executeDescriptor
=
groupedCandidates
[
nextReceivedMessage
.
Group
][
0
];
var
consumerContext
=
new
ConsumerContext
(
executeDescriptor
,
nextReceivedMessage
.
ToMessageContext
());
var
invoker
=
_consumerInvokerFactory
.
CreateInvoker
(
consumerContext
);
await
invoker
.
InvokeAsync
();
await
messageStore
.
ChangeReceivedMessageStateAsync
(
nextReceivedMessage
,
StatusName
.
Succeeded
);
}
catch
(
Exception
ex
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment