From dd9253d0ba127b436ce4c993886f76efd220221d Mon Sep 17 00:00:00 2001 From: Norbert Hartl Date: Sat, 14 Oct 2023 21:43:13 +0200 Subject: [PATCH 1/3] Add handler for notifications and add metrics as one implement of it --- src/Soil-Core/Soil.class.st | 29 +++++++-- src/Soil-Core/SoilMetrics.class.st | 60 +++++++++++++++++++ .../SoilNotificationHandler.class.st | 35 +++++++++++ src/Soil-Core/SoilObjectSegment.class.st | 12 ++-- src/Soil-Core/SoilTransaction.class.st | 27 ++++++--- src/Soil-Serializer/SoilMaterializer.class.st | 2 + src/Soil-Serializer/SoilSerializer.class.st | 2 + 7 files changed, 146 insertions(+), 21 deletions(-) create mode 100644 src/Soil-Core/SoilMetrics.class.st create mode 100644 src/Soil-Core/SoilNotificationHandler.class.st diff --git a/src/Soil-Core/Soil.class.st b/src/Soil-Core/Soil.class.st index 4cc6cc78..24b7ee8d 100644 --- a/src/Soil-Core/Soil.class.st +++ b/src/Soil-Core/Soil.class.st @@ -7,7 +7,8 @@ Class { 'behaviorRegistry', 'semaphore', 'settings', - 'journal' + 'journal', + 'notificationHandler' ], #category : #'Soil-Core-Model' } @@ -129,7 +130,8 @@ Soil >> initializeFilesystem [ journal := SoilJournal new soil: self; initializeFilesystem; - yourself + yourself. + notificationHandler := SoilNotificationHandler new ] { #category : #inspector } @@ -188,11 +190,26 @@ Soil >> newTransaction [ { #category : #transactions } Soil >> newTransaction: aClass [ - ^ aClass new + | txn | + txn := aClass new soil: self; readVersion: self databaseVersion; start; - yourself + yourself. + notificationHandler transactionCreated: txn. + ^ txn +] + +{ #category : #accessing } +Soil >> notificationHandler [ + ^ notificationHandler ifNil: [ + notificationHandler := SoilNotificationHandler new ] +] + +{ #category : #accessing } +Soil >> notificationHandler: anObject [ + + ^ notificationHandler := anObject ] { #category : #accessing } @@ -217,8 +234,8 @@ Soil >> open [ journal := SoilJournal new soil: self; open; - yourself - + yourself. + notificationHandler := SoilNotificationHandler new ] diff --git a/src/Soil-Core/SoilMetrics.class.st b/src/Soil-Core/SoilMetrics.class.st new file mode 100644 index 00000000..5386414d --- /dev/null +++ b/src/Soil-Core/SoilMetrics.class.st @@ -0,0 +1,60 @@ +Class { + #name : #SoilMetrics, + #superclass : #SoilNotificationHandler, + #instVars : [ + 'transactionsCreated', + 'objectsSerialized', + 'clustersWritten', + 'clustersRead', + 'objectsMaterialized', + 'transactionsCommittedReadOnly', + 'transactionsCommittedWrite', + 'transactionsAborted' + ], + #category : #'Soil-Core-Model' +} + +{ #category : #counting } +SoilMetrics >> clusterRead: aSoilPersistentClusterVersion [ + clustersRead := clustersRead + 1 +] + +{ #category : #counting } +SoilMetrics >> clusterWritten: aCollection [ + clustersWritten := clustersWritten + 1 +] + +{ #category : #initialization } +SoilMetrics >> initialize [ + super initialize. + transactionsCreated := 0. + transactionsCommittedReadOnly := 0. + transactionsCommittedWrite := 0. + transactionsAborted := 0. + clustersRead := 0. + clustersWritten := 0. + objectsSerialized := 0. + objectsMaterialized := 0 +] + +{ #category : #counting } +SoilMetrics >> objectMaterialized: aSoilBehaviorDescription [ + objectsMaterialized := objectsMaterialized + 1 +] + +{ #category : #counting } +SoilMetrics >> objectSerialized: aString [ + objectsSerialized := objectsSerialized + 1 +] + +{ #category : #counting } +SoilMetrics >> transactionCommitted: aSoilTransaction [ + aSoilTransaction hasModifications + ifTrue: [ transactionsCommittedWrite := transactionsCommittedWrite + 1 ] + ifFalse: [ transactionsCommittedReadOnly := transactionsCommittedReadOnly + 1 ] +] + +{ #category : #'as yet unclassified' } +SoilMetrics >> transactionCreated: aSoilTransaction [ + transactionsCreated := transactionsCreated + 1 +] diff --git a/src/Soil-Core/SoilNotificationHandler.class.st b/src/Soil-Core/SoilNotificationHandler.class.st new file mode 100644 index 00000000..155f8055 --- /dev/null +++ b/src/Soil-Core/SoilNotificationHandler.class.st @@ -0,0 +1,35 @@ +Class { + #name : #SoilNotificationHandler, + #superclass : #Object, + #category : #'Soil-Core-Model' +} + +{ #category : #counting } +SoilNotificationHandler >> clusterRead: aSoilCluster [ +] + +{ #category : #counting } +SoilNotificationHandler >> clusterWritten: aSoilCluster [ + +] + +{ #category : #counting } +SoilNotificationHandler >> objectMaterialized: aSoilBehaviorDescription [ +] + +{ #category : #counting } +SoilNotificationHandler >> objectSerialized: anObject [ + +] + +{ #category : #events } +SoilNotificationHandler >> transactionAborted: aSoilTransaction [ +] + +{ #category : #counting } +SoilNotificationHandler >> transactionCommitted: aSoilTransaction [ +] + +{ #category : #'as yet unclassified' } +SoilNotificationHandler >> transactionCreated: aSoilTransaction [ +] diff --git a/src/Soil-Core/SoilObjectSegment.class.st b/src/Soil-Core/SoilObjectSegment.class.st index 8df073cf..361d1906 100644 --- a/src/Soil-Core/SoilObjectSegment.class.st +++ b/src/Soil-Core/SoilObjectSegment.class.st @@ -3,7 +3,6 @@ Class { #superclass : #Object, #instVars : [ 'id', - 'soil', 'objectRepository', 'indexFile', 'objectFile', @@ -52,7 +51,9 @@ SoilObjectSegment >> at: anInteger [ | position | position := indexFile positionAt: anInteger. ^ (objectFile atPosition: position) ifNotNil: [ :record | - record objectId: (SoilObjectId segment: id index: anInteger) ] + record objectId: (SoilObjectId segment: id index: anInteger). + self soil notificationHandler clusterRead: record. + record ] ] { #category : #accessing } @@ -61,6 +62,8 @@ SoilObjectSegment >> at: anInteger putBytes: bytes [ position := objectFile size. objectFile appendBytes: bytes. indexFile at: anInteger putPosition: position. + objectRepository ifNotNil: [ + objectRepository soil notificationHandler clusterWritten: bytes ]. ^ position ] @@ -236,11 +239,6 @@ SoilObjectSegment >> soil [ ^ objectRepository soil ] -{ #category : #accessing } -SoilObjectSegment >> soil: aSoil [ - soil := aSoil -] - { #category : #validating } SoilObjectSegment >> validateLastObjectIndex: anInteger [ indexFile validateLastObjectIndex: anInteger diff --git a/src/Soil-Core/SoilTransaction.class.st b/src/Soil-Core/SoilTransaction.class.st index eda7b0bf..8b5d508b 100644 --- a/src/Soil-Core/SoilTransaction.class.st +++ b/src/Soil-Core/SoilTransaction.class.st @@ -20,11 +20,10 @@ Class { { #category : #aborting } SoilTransaction >> abort [ - recordsToCommit := nil. - behaviorDescriptions := nil. - soil := nil. - idMap := nil. - objectMap := nil + soil ifNotNil: [ + soil notificationHandler transactionAborted: self ]. + self basicAbort. + ] { #category : #accessing } @@ -68,6 +67,15 @@ SoilTransaction >> atObjectId: objectId putObject: anObject [ recordsToCommit ifNotNil: [ recordsToCommit add: record ] ] +{ #category : #aborting } +SoilTransaction >> basicAbort [ + recordsToCommit := nil. + behaviorDescriptions := nil. + soil := nil. + idMap := nil. + objectMap := nil +] + { #category : #public } SoilTransaction >> behaviorDescriptionFor: aClass [ | behaviorDescription objectId | @@ -190,7 +198,9 @@ SoilTransaction >> checkpoint [ self prepareRecordsForCommit. "if there are no records to commit we can just return and don't allocate any resources" - recordsToCommit isEmpty ifTrue: [ ^ self ]. + recordsToCommit isEmpty ifTrue: [ + soil notificationHandler transactionCommitted: self. + ^ self ]. "only one transactions is allowed at a time. We use the critical block of the database to avoid parallel committing" soil critical: [ @@ -218,7 +228,8 @@ SoilTransaction >> checkpoint [ "add the journal to the database wide journal so other transaction can access it to resolve older state" soil journal addTransactionJournal: journal ] - ensure: [self releaseLocks ] ] + ensure: [self releaseLocks ] ]. + soil notificationHandler transactionCommitted: self ] @@ -233,7 +244,7 @@ SoilTransaction >> checkpointAndContinue [ SoilTransaction >> commit [ self checkpoint; - abort + basicAbort ] { #category : #actions } diff --git a/src/Soil-Serializer/SoilMaterializer.class.st b/src/Soil-Serializer/SoilMaterializer.class.st index 0b8286e6..6c9bb7fa 100644 --- a/src/Soil-Serializer/SoilMaterializer.class.st +++ b/src/Soil-Serializer/SoilMaterializer.class.st @@ -217,6 +217,8 @@ SoilMaterializer >> nextSoilObject [ { #category : #registry } SoilMaterializer >> registerObject: anObject [ + soil ifNotNil: [ + soil notificationHandler objectMaterialized: anObject ]. objects add: anObject ] diff --git a/src/Soil-Serializer/SoilSerializer.class.st b/src/Soil-Serializer/SoilSerializer.class.st index 0b4d406d..e27b489d 100644 --- a/src/Soil-Serializer/SoilSerializer.class.st +++ b/src/Soil-Serializer/SoilSerializer.class.st @@ -191,6 +191,8 @@ SoilSerializer >> registerObject: anObject ifAbsent: aBlock [ self nextPutExternalReference: externalIndex ] ifFalse: [ objectIdTable add: anObject. + soil ifNotNil: [ + soil notificationHandler objectSerialized: anObject ]. aBlock value ] ] From 3fc193272315948deff609a51a0868e2c9738e4e Mon Sep 17 00:00:00 2001 From: Norbert Hartl Date: Sat, 14 Oct 2023 21:49:46 +0200 Subject: [PATCH 2/3] Added test and accessors --- src/Soil-Core-Tests/SoilTest.class.st | 12 +++++++ src/Soil-Core/SoilMetrics.class.st | 51 +++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/src/Soil-Core-Tests/SoilTest.class.st b/src/Soil-Core-Tests/SoilTest.class.st index d85e5069..8d734bf1 100644 --- a/src/Soil-Core-Tests/SoilTest.class.st +++ b/src/Soil-Core-Tests/SoilTest.class.st @@ -143,6 +143,18 @@ SoilTest >> testInitializeDatabaseFailsIfExisting [ raise: Error ] +{ #category : #tests } +SoilTest >> testMetrics [ + | tx metrics | + soil notificationHandler: SoilMetrics new. + tx := soil newTransaction. + tx root: self simpleGraph. + tx commit. + metrics := soil notificationHandler. + self assert: metrics transactionsCreated equals: 1. + self assert: metrics transactionsCommittedWrite equals: 1 +] + { #category : #tests } SoilTest >> testSerializingClassDescription [ | obj bytes obj2 stream transaction | diff --git a/src/Soil-Core/SoilMetrics.class.st b/src/Soil-Core/SoilMetrics.class.st index 5386414d..5ea1d4e3 100644 --- a/src/Soil-Core/SoilMetrics.class.st +++ b/src/Soil-Core/SoilMetrics.class.st @@ -24,6 +24,18 @@ SoilMetrics >> clusterWritten: aCollection [ clustersWritten := clustersWritten + 1 ] +{ #category : #accessing } +SoilMetrics >> clustersRead [ + + ^ clustersRead +] + +{ #category : #accessing } +SoilMetrics >> clustersWritten [ + + ^ clustersWritten +] + { #category : #initialization } SoilMetrics >> initialize [ super initialize. @@ -47,6 +59,18 @@ SoilMetrics >> objectSerialized: aString [ objectsSerialized := objectsSerialized + 1 ] +{ #category : #accessing } +SoilMetrics >> objectsMaterialized [ + + ^ objectsMaterialized +] + +{ #category : #accessing } +SoilMetrics >> objectsSerialized [ + + ^ objectsSerialized +] + { #category : #counting } SoilMetrics >> transactionCommitted: aSoilTransaction [ aSoilTransaction hasModifications @@ -54,7 +78,34 @@ SoilMetrics >> transactionCommitted: aSoilTransaction [ ifFalse: [ transactionsCommittedReadOnly := transactionsCommittedReadOnly + 1 ] ] +{ #category : #'as yet unclassified' } +SoilMetrics >> transactionCommittedWrite [ + self shouldBeImplemented. +] + { #category : #'as yet unclassified' } SoilMetrics >> transactionCreated: aSoilTransaction [ transactionsCreated := transactionsCreated + 1 ] + +{ #category : #accessing } +SoilMetrics >> transactionsAborted [ + + ^ transactionsAborted +] + +{ #category : #accessing } +SoilMetrics >> transactionsCommittedReadOnly [ + + ^ transactionsCommittedReadOnly +] + +{ #category : #accessing } +SoilMetrics >> transactionsCommittedWrite [ + ^ transactionsCommittedWrite +] + +{ #category : #accessing } +SoilMetrics >> transactionsCreated [ + ^ transactionsCreated +] From f27287c5a30aae9257e9251855ae2a882769f35f Mon Sep 17 00:00:00 2001 From: Norbert Hartl Date: Sat, 14 Oct 2023 21:56:28 +0200 Subject: [PATCH 3/3] Added soil as instVar --- src/Soil-Core/Soil.class.st | 5 +++-- src/Soil-Core/SoilNotificationHandler.class.st | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Soil-Core/Soil.class.st b/src/Soil-Core/Soil.class.st index 24b7ee8d..0a9c1449 100644 --- a/src/Soil-Core/Soil.class.st +++ b/src/Soil-Core/Soil.class.st @@ -132,6 +132,7 @@ Soil >> initializeFilesystem [ initializeFilesystem; yourself. notificationHandler := SoilNotificationHandler new + soil: self ] { #category : #inspector } @@ -202,8 +203,7 @@ Soil >> newTransaction: aClass [ { #category : #accessing } Soil >> notificationHandler [ - ^ notificationHandler ifNil: [ - notificationHandler := SoilNotificationHandler new ] + ^ notificationHandler ] { #category : #accessing } @@ -236,6 +236,7 @@ Soil >> open [ open; yourself. notificationHandler := SoilNotificationHandler new + soil: self ] diff --git a/src/Soil-Core/SoilNotificationHandler.class.st b/src/Soil-Core/SoilNotificationHandler.class.st index 155f8055..1992d4a9 100644 --- a/src/Soil-Core/SoilNotificationHandler.class.st +++ b/src/Soil-Core/SoilNotificationHandler.class.st @@ -1,6 +1,9 @@ Class { #name : #SoilNotificationHandler, #superclass : #Object, + #instVars : [ + 'soil' + ], #category : #'Soil-Core-Model' } @@ -22,6 +25,12 @@ SoilNotificationHandler >> objectSerialized: anObject [ ] +{ #category : #accessing } +SoilNotificationHandler >> soil: anObject [ + + soil := anObject +] + { #category : #events } SoilNotificationHandler >> transactionAborted: aSoilTransaction [ ]