Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
熊鹏飞
/
xxljob220
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
b607bcde
authored
Jul 14, 2017
by
xuxueli
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
执行器路由逻辑优化
parent
2ed78c55
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
30 additions
and
33 deletions
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouter.java
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteBusyover.java
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteConsistentHash.java
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteFailover.java
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteFirst.java
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLFU.java
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLRU.java
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLast.java
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteRandom.java
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteRound.java
xxl-job-admin/src/main/java/com/xxl/job/admin/core/trigger/XxlJobTrigger.java
xxl-job-admin/src/main/webapp/static/js/joblog.index.1.js
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouter.java
View file @
b607bcde
package
com
.
xxl
.
job
.
admin
.
core
.
route
;
package
com
.
xxl
.
job
.
admin
.
core
.
route
;
import
com.xxl.job.admin.core.model.XxlJobLog
;
import
com.xxl.job.core.biz.ExecutorBiz
;
import
com.xxl.job.core.biz.ExecutorBiz
;
import
com.xxl.job.core.biz.model.ReturnT
;
import
com.xxl.job.core.biz.model.ReturnT
;
import
com.xxl.job.core.biz.model.TriggerParam
;
import
com.xxl.job.core.biz.model.TriggerParam
;
...
@@ -21,9 +20,9 @@ public abstract class ExecutorRouter {
...
@@ -21,9 +20,9 @@ public abstract class ExecutorRouter {
*
*
* @param triggerParam
* @param triggerParam
* @param addressList
* @param addressList
* @return
* @return
ReturnT.content: final address
*/
*/
public
abstract
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
,
XxlJobLog
jobLog
);
public
abstract
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
);
/**
/**
* run executor
* run executor
...
...
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteBusyover.java
View file @
b607bcde
package
com
.
xxl
.
job
.
admin
.
core
.
route
.
strategy
;
package
com
.
xxl
.
job
.
admin
.
core
.
route
.
strategy
;
import
com.xxl.job.admin.core.model.XxlJobLog
;
import
com.xxl.job.admin.core.route.ExecutorRouter
;
import
com.xxl.job.admin.core.route.ExecutorRouter
;
import
com.xxl.job.core.biz.ExecutorBiz
;
import
com.xxl.job.core.biz.ExecutorBiz
;
import
com.xxl.job.core.biz.model.ReturnT
;
import
com.xxl.job.core.biz.model.ReturnT
;
...
@@ -19,7 +18,7 @@ public class ExecutorRouteBusyover extends ExecutorRouter {
...
@@ -19,7 +18,7 @@ public class ExecutorRouteBusyover extends ExecutorRouter {
}
}
@Override
@Override
public
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
,
XxlJobLog
jobLog
)
{
public
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
)
{
StringBuffer
idleBeatResultSB
=
new
StringBuffer
();
StringBuffer
idleBeatResultSB
=
new
StringBuffer
();
for
(
String
address
:
addressList
)
{
for
(
String
address
:
addressList
)
{
...
@@ -40,12 +39,14 @@ public class ExecutorRouteBusyover extends ExecutorRouter {
...
@@ -40,12 +39,14 @@ public class ExecutorRouteBusyover extends ExecutorRouter {
// beat success
// beat success
if
(
idleBeatResult
.
getCode
()
==
ReturnT
.
SUCCESS_CODE
)
{
if
(
idleBeatResult
.
getCode
()
==
ReturnT
.
SUCCESS_CODE
)
{
jobLog
.
setExecutorAddress
(
address
);
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
idleBeatResultSB
.
append
(
"<br><br>"
).
append
(
runResult
.
getMsg
());
idleBeatResultSB
.
append
(
"<br><br>"
).
append
(
runResult
.
getMsg
());
return
new
ReturnT
<
String
>(
runResult
.
getCode
(),
idleBeatResultSB
.
toString
());
// result
runResult
.
setMsg
(
idleBeatResultSB
.
toString
());
runResult
.
setContent
(
address
);
return
runResult
;
}
}
}
}
...
...
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteConsistentHash.java
View file @
b607bcde
package
com
.
xxl
.
job
.
admin
.
core
.
route
.
strategy
;
package
com
.
xxl
.
job
.
admin
.
core
.
route
.
strategy
;
import
com.xxl.job.admin.core.model.XxlJobLog
;
import
com.xxl.job.admin.core.route.ExecutorRouter
;
import
com.xxl.job.admin.core.route.ExecutorRouter
;
import
com.xxl.job.core.biz.model.ReturnT
;
import
com.xxl.job.core.biz.model.ReturnT
;
import
com.xxl.job.core.biz.model.TriggerParam
;
import
com.xxl.job.core.biz.model.TriggerParam
;
...
@@ -78,13 +77,13 @@ public class ExecutorRouteConsistentHash extends ExecutorRouter {
...
@@ -78,13 +77,13 @@ public class ExecutorRouteConsistentHash extends ExecutorRouter {
}
}
@Override
@Override
public
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
,
XxlJobLog
jobLog
)
{
public
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
)
{
// address
// address
String
address
=
route
(
triggerParam
.
getJobId
(),
addressList
);
String
address
=
route
(
triggerParam
.
getJobId
(),
addressList
);
jobLog
.
setExecutorAddress
(
address
);
// run executor
// run executor
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
runResult
.
setContent
(
address
);
return
runResult
;
return
runResult
;
}
}
}
}
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteFailover.java
View file @
b607bcde
package
com
.
xxl
.
job
.
admin
.
core
.
route
.
strategy
;
package
com
.
xxl
.
job
.
admin
.
core
.
route
.
strategy
;
import
com.xxl.job.admin.core.model.XxlJobLog
;
import
com.xxl.job.admin.core.route.ExecutorRouter
;
import
com.xxl.job.admin.core.route.ExecutorRouter
;
import
com.xxl.job.core.biz.ExecutorBiz
;
import
com.xxl.job.core.biz.ExecutorBiz
;
import
com.xxl.job.core.biz.model.ReturnT
;
import
com.xxl.job.core.biz.model.ReturnT
;
...
@@ -19,7 +18,7 @@ public class ExecutorRouteFailover extends ExecutorRouter {
...
@@ -19,7 +18,7 @@ public class ExecutorRouteFailover extends ExecutorRouter {
}
}
@Override
@Override
public
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
,
XxlJobLog
jobLog
)
{
public
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
)
{
StringBuffer
beatResultSB
=
new
StringBuffer
();
StringBuffer
beatResultSB
=
new
StringBuffer
();
for
(
String
address
:
addressList
)
{
for
(
String
address
:
addressList
)
{
...
@@ -40,12 +39,14 @@ public class ExecutorRouteFailover extends ExecutorRouter {
...
@@ -40,12 +39,14 @@ public class ExecutorRouteFailover extends ExecutorRouter {
// beat success
// beat success
if
(
beatResult
.
getCode
()
==
ReturnT
.
SUCCESS_CODE
)
{
if
(
beatResult
.
getCode
()
==
ReturnT
.
SUCCESS_CODE
)
{
jobLog
.
setExecutorAddress
(
address
);
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
beatResultSB
.
append
(
"<br><br>"
).
append
(
runResult
.
getMsg
());
beatResultSB
.
append
(
"<br><br>"
).
append
(
runResult
.
getMsg
());
return
new
ReturnT
<
String
>(
runResult
.
getCode
(),
beatResultSB
.
toString
());
// result
runResult
.
setMsg
(
beatResultSB
.
toString
());
runResult
.
setContent
(
address
);
return
runResult
;
}
}
}
}
return
new
ReturnT
<
String
>(
ReturnT
.
FAIL_CODE
,
beatResultSB
.
toString
());
return
new
ReturnT
<
String
>(
ReturnT
.
FAIL_CODE
,
beatResultSB
.
toString
());
...
...
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteFirst.java
View file @
b607bcde
...
@@ -17,14 +17,14 @@ public class ExecutorRouteFirst extends ExecutorRouter {
...
@@ -17,14 +17,14 @@ public class ExecutorRouteFirst extends ExecutorRouter {
}
}
@Override
@Override
public
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
,
XxlJobLog
jobLog
)
{
public
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
)
{
// address
// address
String
address
=
route
(
triggerParam
.
getJobId
(),
addressList
);
String
address
=
route
(
triggerParam
.
getJobId
(),
addressList
);
jobLog
.
setExecutorAddress
(
address
);
// run executor
// run executor
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
runResult
.
setContent
(
address
);
return
runResult
;
return
runResult
;
}
}
}
}
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLFU.java
View file @
b607bcde
package
com
.
xxl
.
job
.
admin
.
core
.
route
.
strategy
;
package
com
.
xxl
.
job
.
admin
.
core
.
route
.
strategy
;
import
com.xxl.job.admin.core.model.XxlJobLog
;
import
com.xxl.job.admin.core.route.ExecutorRouter
;
import
com.xxl.job.admin.core.route.ExecutorRouter
;
import
com.xxl.job.core.biz.model.ReturnT
;
import
com.xxl.job.core.biz.model.ReturnT
;
import
com.xxl.job.core.biz.model.TriggerParam
;
import
com.xxl.job.core.biz.model.TriggerParam
;
...
@@ -57,14 +56,14 @@ public class ExecutorRouteLFU extends ExecutorRouter {
...
@@ -57,14 +56,14 @@ public class ExecutorRouteLFU extends ExecutorRouter {
}
}
@Override
@Override
public
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
,
XxlJobLog
jobLog
)
{
public
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
)
{
// address
// address
String
address
=
route
(
triggerParam
.
getJobId
(),
addressList
);
String
address
=
route
(
triggerParam
.
getJobId
(),
addressList
);
jobLog
.
setExecutorAddress
(
address
);
// run executor
// run executor
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
runResult
.
setContent
(
address
);
return
runResult
;
return
runResult
;
}
}
...
...
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLRU.java
View file @
b607bcde
package
com
.
xxl
.
job
.
admin
.
core
.
route
.
strategy
;
package
com
.
xxl
.
job
.
admin
.
core
.
route
.
strategy
;
import
com.xxl.job.admin.core.model.XxlJobLog
;
import
com.xxl.job.admin.core.route.ExecutorRouter
;
import
com.xxl.job.admin.core.route.ExecutorRouter
;
import
com.xxl.job.core.biz.model.ReturnT
;
import
com.xxl.job.core.biz.model.ReturnT
;
import
com.xxl.job.core.biz.model.TriggerParam
;
import
com.xxl.job.core.biz.model.TriggerParam
;
...
@@ -56,14 +55,14 @@ public class ExecutorRouteLRU extends ExecutorRouter {
...
@@ -56,14 +55,14 @@ public class ExecutorRouteLRU extends ExecutorRouter {
@Override
@Override
public
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
,
XxlJobLog
jobLog
)
{
public
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
)
{
// address
// address
String
address
=
route
(
triggerParam
.
getJobId
(),
addressList
);
String
address
=
route
(
triggerParam
.
getJobId
(),
addressList
);
jobLog
.
setExecutorAddress
(
address
);
// run executor
// run executor
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
runResult
.
setContent
(
address
);
return
runResult
;
return
runResult
;
}
}
...
...
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLast.java
View file @
b607bcde
...
@@ -17,13 +17,13 @@ public class ExecutorRouteLast extends ExecutorRouter {
...
@@ -17,13 +17,13 @@ public class ExecutorRouteLast extends ExecutorRouter {
}
}
@Override
@Override
public
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
,
XxlJobLog
jobLog
)
{
public
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
)
{
// address
// address
String
address
=
route
(
triggerParam
.
getJobId
(),
addressList
);
String
address
=
route
(
triggerParam
.
getJobId
(),
addressList
);
jobLog
.
setExecutorAddress
(
address
);
// run executor
// run executor
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
runResult
.
setContent
(
address
);
return
runResult
;
return
runResult
;
}
}
}
}
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteRandom.java
View file @
b607bcde
package
com
.
xxl
.
job
.
admin
.
core
.
route
.
strategy
;
package
com
.
xxl
.
job
.
admin
.
core
.
route
.
strategy
;
import
com.xxl.job.admin.core.model.XxlJobLog
;
import
com.xxl.job.admin.core.route.ExecutorRouter
;
import
com.xxl.job.admin.core.route.ExecutorRouter
;
import
com.xxl.job.core.biz.model.ReturnT
;
import
com.xxl.job.core.biz.model.ReturnT
;
import
com.xxl.job.core.biz.model.TriggerParam
;
import
com.xxl.job.core.biz.model.TriggerParam
;
...
@@ -21,13 +20,13 @@ public class ExecutorRouteRandom extends ExecutorRouter {
...
@@ -21,13 +20,13 @@ public class ExecutorRouteRandom extends ExecutorRouter {
}
}
@Override
@Override
public
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
,
XxlJobLog
jobLog
)
{
public
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
)
{
// address
// address
String
address
=
route
(
triggerParam
.
getJobId
(),
addressList
);
String
address
=
route
(
triggerParam
.
getJobId
(),
addressList
);
jobLog
.
setExecutorAddress
(
address
);
// run executor
// run executor
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
runResult
.
setContent
(
address
);
return
runResult
;
return
runResult
;
}
}
...
...
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteRound.java
View file @
b607bcde
package
com
.
xxl
.
job
.
admin
.
core
.
route
.
strategy
;
package
com
.
xxl
.
job
.
admin
.
core
.
route
.
strategy
;
import
com.xxl.job.admin.core.model.XxlJobLog
;
import
com.xxl.job.admin.core.route.ExecutorRouter
;
import
com.xxl.job.admin.core.route.ExecutorRouter
;
import
com.xxl.job.core.biz.model.ReturnT
;
import
com.xxl.job.core.biz.model.ReturnT
;
import
com.xxl.job.core.biz.model.TriggerParam
;
import
com.xxl.job.core.biz.model.TriggerParam
;
...
@@ -36,14 +35,14 @@ public class ExecutorRouteRound extends ExecutorRouter {
...
@@ -36,14 +35,14 @@ public class ExecutorRouteRound extends ExecutorRouter {
@Override
@Override
public
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
,
XxlJobLog
jobLog
)
{
public
ReturnT
<
String
>
routeRun
(
TriggerParam
triggerParam
,
ArrayList
<
String
>
addressList
)
{
// address
// address
String
address
=
route
(
triggerParam
.
getJobId
(),
addressList
);
String
address
=
route
(
triggerParam
.
getJobId
(),
addressList
);
jobLog
.
setExecutorAddress
(
address
);
// run executor
// run executor
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
runResult
.
setContent
(
address
);
return
runResult
;
return
runResult
;
}
}
}
}
xxl-job-admin/src/main/java/com/xxl/job/admin/core/trigger/XxlJobTrigger.java
View file @
b607bcde
...
@@ -86,17 +86,18 @@ public class XxlJobTrigger {
...
@@ -86,17 +86,18 @@ public class XxlJobTrigger {
triggerParam
.
setLogDateTim
(
jobLog
.
getTriggerTime
().
getTime
());
triggerParam
.
setLogDateTim
(
jobLog
.
getTriggerTime
().
getTime
());
// 4.2、trigger-run (route run / trigger remote executor)
// 4.2、trigger-run (route run / trigger remote executor)
triggerResult
=
executorRouteStrategyEnum
.
getRouter
().
routeRun
(
triggerParam
,
addressList
,
jobLog
);
triggerResult
=
executorRouteStrategyEnum
.
getRouter
().
routeRun
(
triggerParam
,
addressList
);
triggerMsgSb
.
append
(
"<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>"
).
append
(
triggerResult
.
getMsg
());
triggerMsgSb
.
append
(
"<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>"
).
append
(
triggerResult
.
getMsg
());
// 4.3、trigger (fail retry)
// 4.3、trigger (fail retry)
if
(
triggerResult
.
getCode
()!=
ReturnT
.
SUCCESS_CODE
&&
failStrategy
==
ExecutorFailStrategyEnum
.
FAIL_RETRY
)
{
if
(
triggerResult
.
getCode
()!=
ReturnT
.
SUCCESS_CODE
&&
failStrategy
==
ExecutorFailStrategyEnum
.
FAIL_RETRY
)
{
triggerResult
=
executorRouteStrategyEnum
.
getRouter
().
routeRun
(
triggerParam
,
addressList
,
jobLog
);
triggerResult
=
executorRouteStrategyEnum
.
getRouter
().
routeRun
(
triggerParam
,
addressList
);
triggerMsgSb
.
append
(
"<br><br><span style=\"color:#F39C12;\" > >>>>>>>>>>>失败重试<<<<<<<<<<< </span><br>"
).
append
(
triggerResult
.
getMsg
());
triggerMsgSb
.
append
(
"<br><br><span style=\"color:#F39C12;\" > >>>>>>>>>>>失败重试<<<<<<<<<<< </span><br>"
).
append
(
triggerResult
.
getMsg
());
}
}
}
}
// 5、save trigger-info
// 5、save trigger-info
jobLog
.
setExecutorAddress
(
triggerResult
.
getContent
());
jobLog
.
setTriggerCode
(
triggerResult
.
getCode
());
jobLog
.
setTriggerCode
(
triggerResult
.
getCode
());
jobLog
.
setTriggerMsg
(
triggerMsgSb
.
toString
());
jobLog
.
setTriggerMsg
(
triggerMsgSb
.
toString
());
XxlJobDynamicScheduler
.
xxlJobLogDao
.
updateTriggerInfo
(
jobLog
);
XxlJobDynamicScheduler
.
xxlJobLogDao
.
updateTriggerInfo
(
jobLog
);
...
...
xxl-job-admin/src/main/webapp/static/js/joblog.index.1.js
View file @
b607bcde
...
@@ -110,7 +110,7 @@ $(function() {
...
@@ -110,7 +110,7 @@ $(function() {
}
}
var
temp
=
''
;
var
temp
=
''
;
temp
+=
'执行器地址:'
+
row
.
executorAddress
;
temp
+=
'执行器地址:'
+
(
row
.
executorAddress
?
row
.
executorAddress
:
''
)
;
temp
+=
'<br>运行模式:'
+
glueTypeTitle
;
temp
+=
'<br>运行模式:'
+
glueTypeTitle
;
temp
+=
'<br>任务参数:'
+
row
.
executorParam
;
temp
+=
'<br>任务参数:'
+
row
.
executorParam
;
...
...
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