1717
1818'use strict' ;
1919
20- const timeUtils = require ( '../lib/Time.js' ) ;
2120const msgUtils = require ( '../utils/message_utils.js' ) ;
2221const EventEmitter = require ( 'events' ) ;
22+ const Ultron = require ( 'ultron' ) ;
2323
2424const ActionServerInterface = require ( '../lib/ActionServerInterface.js' ) ;
2525const GoalHandle = require ( './GoalHandle.js' ) ;
2626const Time = require ( '../lib/Time.js' ) ;
2727
28+ const log = require ( '../lib/Logging.js' ) . getLogger ( 'actionlib_nodejs' ) ;
29+ const ThisNode = require ( '../lib/ThisNode.js' ) ;
30+
2831let GoalIdMsg = null ;
2932let GoalStatusMsg = null ;
3033let GoalStatusArrayMsg = null ;
@@ -49,7 +52,27 @@ class ActionServer extends EventEmitter {
4952 GoalStatusArrayMsg = msgUtils . requireMsgPackage ( 'actionlib_msgs' ) . msg . GoalStatusArray ;
5053 }
5154
52- this . _asInterface = new ActionServerInterface ( options ) ;
55+ this . _options = options ;
56+
57+ this . _pubSeqs = {
58+ result : 0 ,
59+ feedback : 0 ,
60+ status : 0
61+ } ;
62+
63+ this . _goalHandleList = [ ] ;
64+ this . _goalHandleCache = { } ;
65+
66+ this . _lastCancelStamp = Time . epoch ( ) ;
67+
68+ this . _statusListTimeout = { secs : 5 , nsecs : 0 } ;
69+ this . _shutdown = false ;
70+ this . _ultron = new Ultron ( ThisNode ) ;
71+ }
72+
73+ start ( ) {
74+ this . _started = true ;
75+ this . _asInterface = new ActionServerInterface ( this . _options ) ;
5376
5477 this . _asInterface . on ( 'goal' , this . _handleGoal . bind ( this ) ) ;
5578 this . _asInterface . on ( 'cancel' , this . _handleCancel . bind ( this ) ) ;
@@ -63,36 +86,50 @@ class ActionServer extends EventEmitter {
6386 actionFeedback : msgUtils . getHandlerForMsgType ( actionType + 'ActionFeedback' )
6487 } ;
6588
66- this . _pubSeqs = {
67- result : 0 ,
68- feedback : 0 ,
69- status : 0
70- } ;
89+ this . publishStatus ( ) ;
7190
72- this . _goalHandleList = [ ] ;
73- this . _goalHandleCache = { } ;
91+ let statusFreq = 5 ;
92+ if ( this . _options . statusFrequency !== undefined ) {
93+ if ( typeof this . _options . statusFrequency !== 'number' ) {
94+ throw new Error ( `Invalid value (${ this . _options . statusFrequency } ) for statusFrequency - expected number` ) ;
95+ }
7496
75- this . _lastCancelStamp = timeUtils . epoch ( ) ;
97+ statusFreq = this . _options . statusFrequency ;
98+ }
7699
77- this . _statusFrequency = 5 ;
78- this . _statusListTimeout = 5 ;
79- this . _statusHandle = null ;
100+ if ( statusFreq > 0 ) {
101+ this . _statusFreqInt = setInterval ( ( ) => {
102+ this . publishStatus ( ) ;
103+ } , 1000 / statusFreq ) ;
104+ }
80105
81- this . _started = false ;
106+ // FIXME: how to handle shutdown? Should user be responsible?
107+ // should we check for shutdown in interval instead of listening
108+ // to events here?
109+ this . _ultron . once ( 'shutdown' , ( ) => { this . shutdown ( ) ; } ) ;
82110 }
83111
84112 generateGoalId ( ) {
85113 return this . _asInterface . generateGoalId ( ) ;
86114 }
87115
88- start ( ) {
89- this . _started = true ;
90- this . _statusHandle = setInterval ( this . publishStatus . bind ( this ) , 1000 / this . _statusFrequency ) ;
91- }
92-
93116 shutdown ( ) {
94- clearInterval ( this . _statusHandle ) ;
95- return this . _asInterface . shutdown ( ) ;
117+ if ( ! this . _shutdown ) {
118+ this . _shutdown = true ;
119+ this . removeAllListeners ( ) ;
120+
121+ clearInterval ( this . _statusFreqInt ) ;
122+ this . _statusFreqInt = null ;
123+
124+ this . _ultron . destroy ( ) ;
125+ this . _ultron = null ;
126+
127+ if ( this . _asInterface ) {
128+ return this . _asInterface . shutdown ( ) ;
129+ }
130+ }
131+ // else
132+ return Promise . resolve ( ) ;
96133 }
97134
98135 _getGoalHandle ( id ) {
@@ -109,9 +146,9 @@ class ActionServer extends EventEmitter {
109146 let handle = this . _getGoalHandle ( newGoalId ) ;
110147
111148 if ( handle ) {
112- if ( handle . _status . status === GoalStatuses . RECALLING ) {
113- handle . _status . status = GoalStatuses . RECALLED ;
114- this . publishResult ( handle . _status , this . _createMessage ( 'result' ) ) ;
149+ // check if we already received a request to cancel this goal
150+ if ( handle . getStatusId ( ) === GoalStatuses . RECALLING ) {
151+ handle . setCancelled ( this . _createMessage ( 'result' ) ) ;
115152 }
116153
117154 handle . _destructionTime = msg . goal_id . stamp ;
@@ -124,8 +161,8 @@ class ActionServer extends EventEmitter {
124161
125162 const goalStamp = msg . goal_id . stamp ;
126163 // check if this goal has already been cancelled based on its timestamp
127- if ( ! timeUtils . isZeroTime ( goalStamp ) &&
128- timeUtils . timeComp ( goalStamp , this . _lastCancelStamp ) < 0 ) {
164+ if ( ! Time . isZeroTime ( goalStamp ) &&
165+ Time . timeComp ( goalStamp , this . _lastCancelStamp ) < 0 ) {
129166 handle . setCancelled ( this . _createMessage ( 'result' ) ) ;
130167 return false ;
131168 }
@@ -144,7 +181,7 @@ class ActionServer extends EventEmitter {
144181
145182 const cancelId = msg . id ;
146183 const cancelStamp = msg . stamp ;
147- const cancelStampIsZero = timeUtils . isZeroTime ( cancelStamp ) ;
184+ const cancelStampIsZero = Time . isZeroTime ( cancelStamp ) ;
148185
149186 const shouldCancelEverything = ( cancelId === '' && cancelStampIsZero ) ;
150187
@@ -153,12 +190,12 @@ class ActionServer extends EventEmitter {
153190 for ( let i = 0 , len = this . _goalHandleList . length ; i < len ; ++ i ) {
154191 const handle = this . _goalHandleList [ i ] ;
155192 const handleId = handle . id ;
156- const handleStamp = handle . _status . goal_id . stamp ;
193+ const handleStamp = handle . getStatus ( ) . goal_id . stamp ;
157194
158195 if ( shouldCancelEverything ||
159196 cancelId === handleId ||
160- ( ! timeUtils . isZeroTime ( handleStamp ) &&
161- timeUtils . timeComp ( handleStamp , cancelStamp ) < 0 ) )
197+ ( ! Time . isZeroTime ( handleStamp ) &&
198+ Time . timeComp ( handleStamp , cancelStamp ) < 0 ) )
162199 {
163200 if ( cancelId === handleId ) {
164201 goalIdFound = true ;
@@ -179,7 +216,7 @@ class ActionServer extends EventEmitter {
179216 }
180217
181218 // update the last cancel stamp if new one occurred later
182- if ( timeUtils . timeComp ( cancelStamp , this . _lastCancelStamp ) > 0 ) {
219+ if ( Time . timeComp ( cancelStamp , this . _lastCancelStamp ) > 0 ) {
183220 this . _lastCancelStamp = cancelStamp ;
184221 }
185222 }
@@ -207,16 +244,15 @@ class ActionServer extends EventEmitter {
207244
208245 let goalsToRemove = new Set ( ) ;
209246
210- const now = timeUtils . toNumber ( Time . now ( ) ) ;
247+ const now = Time . now ( ) ;
211248
212249 for ( let i = 0 , len = this . _goalHandleList . length ; i < len ; ++ i ) {
213250 const goalHandle = this . _goalHandleList [ i ] ;
214251 msg . status_list . push ( goalHandle . getGoalStatus ( ) ) ;
215252
216253 const t = goalHandle . _destructionTime ;
217- const tNum = timeUtils . toNumber ( t ) ;
218- if ( ! timeUtils . isZeroTime ( t ) &&
219- timeUtils . toNumber ( t ) + this . _statusListTimeout < now )
254+ if ( ! Time . isZeroTime ( t ) &&
255+ Time . lt ( Time . add ( t , this . _statusListTimeout ) , now ) )
220256 {
221257 goalsToRemove . add ( goalHandle ) ;
222258 }
0 commit comments