This repository was archived by the owner on Oct 3, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommand_bus.coffee
More file actions
97 lines (80 loc) · 3.3 KB
/
command_bus.coffee
File metadata and controls
97 lines (80 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
DomainRepository = require "./domain_repository"
CommandBusServer = require "./command_bus_server"
Profiler = require "./profiler"
class CommandBus
constructor: ({@domainRepository, @logger, @port, @replaying}) ->
throw new Error "Missing domain repository" unless @domainRepository?
throw new Error "Missing logger" unless @logger?
if @port && !@replaying
@server = new CommandBusServer commandBus: @, port: @port, logger: @logger
@server.listen @port
@commandHandlers = {}
registerCommandHandler: (commandHandler) ->
commandName = commandHandler.getCommandName()
throw new Error "A command and its handler for command named \"#{commandName}\" were already registered" if @commandHandlers[commandName]?
@commandHandlers[commandName] = commandHandler
createNewUid: (callback) ->
@domainRepository.createNewUid callback
executeCommand: (command, callback) ->
domainRepository = @domainRepository
logger = @logger
validateCommand = (callback) ->
if (command.validate?)
command.validate callback
else
callback()
validateCommand (err) =>
return callback err if err?
@instantiateHandlerForCommand command, (err, commandHandler) ->
return callback err if err?
p = new Profiler "CommandBus#executeCommand(command execution)", logger
if commandHandler.validate?
p1 = new Profiler "CommandBus#executeCommand(validation)", logger
p2 = new Profiler "CommandBus#executeCommand(run)", logger
transaction = (done) ->
p.start()
p1.start()
commandHandler.validate (err, result) ->
p1.end()
if err?
logger.warning "executeCommand", "validation error", err
callback err
done err
return
callback null, result
p2.start()
commandHandler.run (args...) ->
p2.end()
p.end()
done args...
transaction.callback = callback
else
transaction = (done) ->
p.start()
commandHandler.run (args...) ->
p.end()
done args...
domainRepository.queueTransaction transaction
logger.log "CommandBus#executeCommand", "transaction for command '#{command.getName()}' queued"
callback null unless commandHandler.validate?
deserializeCommand: (commandName, payload, callback) ->
@getHandlerForCommandName commandName, (err, CommandHandler) ->
return callback err if err?
Command = CommandHandler.getCommand()
command = new Command payload
callback null, command
instantiateHandlerForCommand: (command, callback) ->
commandName = command.getName()
@getHandlerForCommandName commandName, (err, CommandHandler) ->
return callback err if err?
commandHandler = new CommandHandler command
callback null, commandHandler
getHandlerForCommandName: (commandName, callback) ->
CommandHandler = @commandHandlers[commandName]
if not CommandHandler?
callback new Error "No handler for command \"#{commandName}\" was found"
else
callback null, CommandHandler
close: (callback) ->
@server.close callback
module.exports = CommandBus