diff --git a/src/Molecule-Tests/MolCompleteComponentForkedImpl.class.st b/src/Molecule-Tests/MolCompleteComponentForkedImpl.class.st new file mode 100644 index 0000000..859d43a --- /dev/null +++ b/src/Molecule-Tests/MolCompleteComponentForkedImpl.class.st @@ -0,0 +1,62 @@ +" +This component send an event in a forked thread +" +Class { + #name : #MolCompleteComponentForkedImpl, + #superclass : #MolCompleteComponentImpl, + #instVars : [ + 'service' + ], + #category : #'Molecule-Tests-Resources - Components' +} + +{ #category : #'life cycle' } +MolCompleteComponentForkedImpl >> componentActivate [ + + super componentActivate. + + self startEventSending +] + +{ #category : #'life cycle' } +MolCompleteComponentForkedImpl >> componentPassivate [ + + self stopEventSending. + + super componentPassivate +] + +{ #category : #private } +MolCompleteComponentForkedImpl >> doEventSending [ + + | notifier | + notifier := self getMolUsedEventsNotifier. + + "simulate a processing time here" + 100 milliSecond wait. + + notifier event +] + +{ #category : #private } +MolCompleteComponentForkedImpl >> startEventSending [ + + service := TKTParameterizableService new + step: [ self doEventSending ]; + name: 'Molecule Test - sending event'; + stepDelay: 50 milliSecond. + + service start +] + +{ #category : #private } +MolCompleteComponentForkedImpl >> stopEventSending [ + + service stop +] + +{ #category : #accessing } +MolCompleteComponentForkedImpl >> thread [ + + ^ service +] diff --git a/src/Molecule-Tests/MolComponentImplTest.class.st b/src/Molecule-Tests/MolComponentImplTest.class.st index c1dca94..43af80b 100644 --- a/src/Molecule-Tests/MolComponentImplTest.class.st +++ b/src/Molecule-Tests/MolComponentImplTest.class.st @@ -582,6 +582,21 @@ MolComponentImplTest >> testParametersProviders [ self assert: component parametersProviders isEmpty. ] +{ #category : #'tests - connecting - events producers' } +MolComponentImplTest >> testSendEventInAForkDuringCleanUp [ + + | component | + component := MolCompleteComponentForkedImpl start. + self assert: component thread isRunning. + + 10 milliSecond wait. + MolComponentManager cleanUp. + + "waiting for thread loop" + 5 second wait. "here no error" + self deny: component thread isRunning +] + { #category : #tests } MolComponentImplTest >> testServicesDoIfNone [ diff --git a/src/Molecule-Tests/MolEventNotifierTest.class.st b/src/Molecule-Tests/MolEventNotifierTest.class.st index e6488d2..d569018 100644 --- a/src/Molecule-Tests/MolEventNotifierTest.class.st +++ b/src/Molecule-Tests/MolEventNotifierTest.class.st @@ -7,19 +7,23 @@ Class { #category : #'Molecule-Tests-Cases' } -{ #category : #test } -MolEventNotifierTest >> setUp [ - - MolComponentManager cleanUp. +{ #category : #running } +MolEventNotifierTest >> setUp [ + + super setUp. + + MolComponentManager cleanUp ] -{ #category : #test } -MolEventNotifierTest >> tearDown [ - +{ #category : #running } +MolEventNotifierTest >> tearDown [ + MolComponentManager cleanUp. + + super tearDown ] -{ #category : #test } +{ #category : #tests } MolEventNotifierTest >> testActivate [ | notifier | notifier := MolEventNotifier new. @@ -27,7 +31,7 @@ MolEventNotifierTest >> testActivate [ self assert: notifier isActive. ] -{ #category : #test } +{ #category : #tests } MolEventNotifierTest >> testDeactivate [ | notifier | notifier := MolEventNotifier new. @@ -36,7 +40,7 @@ MolEventNotifierTest >> testDeactivate [ self assert: notifier isActive not. ] -{ #category : #test } +{ #category : #tests } MolEventNotifierTest >> testDoesNotUnderstand [ | originator notifier error | originator := MolCompleteComponentImpl new. @@ -50,7 +54,7 @@ MolEventNotifierTest >> testDoesNotUnderstand [ self assert: (error isKindOf: MessageNotUnderstood). ] -{ #category : #test } +{ #category : #tests } MolEventNotifierTest >> testDoesNotUnderstandWithoutCorrectDefinition [ | notifier error | notifier := MolEventNotifier new. @@ -62,41 +66,55 @@ MolEventNotifierTest >> testDoesNotUnderstandWithoutCorrectDefinition [ notifier event. "Make a log but not raised an error" ] -{ #category : #test } +{ #category : #tests } MolEventNotifierTest >> testInitialize [ + | notifier | notifier := MolEventNotifier new. self assert: notifier interface isNil. self assert: notifier originator isNil. - self assert: notifier isActive equals: false. + self deny: notifier isActive ] -{ #category : #test } +{ #category : #tests } MolEventNotifierTest >> testInterfaceOriginator [ + | notifier originator | originator := MolCompleteComponentImpl new. - notifier := MolEventNotifier interface: MolUsedEvents originator: originator. + notifier := MolEventNotifier + interface: MolUsedEvents + originator: originator. self assert: notifier interface identicalTo: MolUsedEvents. self assert: notifier originator identicalTo: originator. - self assert: notifier isActive equals: false. + self deny: notifier isActive ] -{ #category : #test } +{ #category : #tests } MolEventNotifierTest >> testIsNotFoundEventsNotifier [ | notifier | notifier := MolEventNotifier new. self assert: notifier isNotFoundEventsNotifier not. ] -{ #category : #test } +{ #category : #tests } MolEventNotifierTest >> testRelease [ - | notifier originator | + + | notifier originator error | originator := MolCompleteComponentImpl new. - notifier := MolEventNotifier interface: MolUsedEvents originator: originator. + notifier := MolEventNotifier + interface: MolUsedEvents + originator: originator. notifier activate. - + notifier release. - self assert: notifier interface isNil. self assert: notifier originator isNil. - self assert: notifier isActive equals: false. + self deny: notifier isActive. + + "try to send an event when release: do nothing" + notifier event. + + "MolUsedEvent>>subEvent not exists: continue to raise not understood message to identify call problems" + error := nil. + [notifier subEvent] on: Error do:[ :e | error := e ]. + self assert: (error isKindOf: MessageNotUnderstood). ] diff --git a/src/Molecule-Tests/MolUtilsTest.class.st b/src/Molecule-Tests/MolUtilsTest.class.st index 57956fd..84a8381 100644 --- a/src/Molecule-Tests/MolUtilsTest.class.st +++ b/src/Molecule-Tests/MolUtilsTest.class.st @@ -58,7 +58,7 @@ MolUtilsTest >> testActivateComponents [ { #category : #tests } MolUtilsTest >> testAllComponentImplementationClassesOfType [ - self assert: (MolUtils allComponentImplementationClassesOfType: MolCompleteComponent) size equals: 6. + self assert: (MolUtils allComponentImplementationClassesOfType: MolCompleteComponent) size equals: 7. ] { #category : #tests } diff --git a/src/Molecule/MolEventNotifier.class.st b/src/Molecule/MolEventNotifier.class.st index e1e36f5..ea855d9 100644 --- a/src/Molecule/MolEventNotifier.class.st +++ b/src/Molecule/MolEventNotifier.class.st @@ -21,62 +21,59 @@ MolEventNotifier class >> interface: aMolUsedEvents originator: aComponent [ { #category : #actions } MolEventNotifier >> activate [ + isActive := true ] { #category : #actions } MolEventNotifier >> deactivate [ + isActive := false ] { #category : #'reflective operations' } MolEventNotifier >> doesNotUnderstand: aMessage [ "Event message is called by a Notifier, the message not exists in MolEventNotifier so the system called doesNotUnderstand: message. Check if the event message is known by the event interface and trigger the event." - | isEventExist | - interface ifNil:[ ^ super doesNotUnderstand: aMessage ]. - originator ifNil:[ - MolUtils log: 'Originator not defined for event: ' , aMessage selector. - ^ self - ]. - isEventExist := interface includesSelector: aMessage selector. - - isEventExist - ifTrue: [ - isActive - ifTrue: [ - MolUtils log: originator printString , ' send event: ' , aMessage selector. - originator triggerEvent: aMessage selector withArguments: aMessage arguments. - ] ifFalse: [ - MolUtils log: 'An inactive component: ', originator printString , ' send event: ' , aMessage selector. ]. - ^ self. - ] ifFalse: [ - MolUtils log: originator printString , ' send an undefined event: ' , aMessage selector. - ]. - - ^ super doesNotUnderstand: aMessage - - - + + self interface + ifNil: [ "cannot interpret the message, return not understand" + ^ super doesNotUnderstand: aMessage ] + ifNotNil: [ + | isEventExist | + isEventExist := self interface includesSelector: aMessage selector. + isEventExist + ifFalse: [ + MolUtils log: + self originator printString , ' send an undefined event: ' + , aMessage selector. + "the event not exists, stop production here and return not understand" + ^ super doesNotUnderstand: aMessage ] + ifTrue: [ self produceEvent: aMessage ] ] ] -{ #category : #'initialize-release' } +{ #category : #initialization } MolEventNotifier >> initialize [ + super initialize. - self deactivate. + + self deactivate ] { #category : #accessing } MolEventNotifier >> interface [ + ^ interface ] { #category : #accessing } MolEventNotifier >> interface: anInterface [ + interface := anInterface ] { #category : #accessing } MolEventNotifier >> isActive [ + ^ isActive ] @@ -88,18 +85,43 @@ MolEventNotifier >> isFoundEventsNotifier [ { #category : #accessing } MolEventNotifier >> originator [ + ^ originator ] { #category : #accessing } MolEventNotifier >> originator: aComponent [ + originator := aComponent ] -{ #category : #'initialize-release' } +{ #category : #private } +MolEventNotifier >> produceEvent: aMessage [ + "Produce an event to offered components" + + "If the notifier is not active, stop production here" + self isActive ifFalse: [ ^ self ]. + + "If there is no originator, stop the production here" + self originator ifNil: [ + MolUtils log: + 'Originator not defined for event: ' , aMessage selector. + ^ self ]. + + MolUtils log: + self originator printString , ' send event: ' , aMessage selector. + + "produce the event using object trigger mecanism" + self originator + triggerEvent: aMessage selector + withArguments: aMessage arguments +] + +{ #category : #dependencies } MolEventNotifier >> release [ + self deactivate. - interface := nil. originator := nil. - super release. + + super release ]