Skip to content

Commit

Permalink
Adding new SRE network module
Browse files Browse the repository at this point in the history
  • Loading branch information
ngaud committed Oct 22, 2020
1 parent 7118262 commit 50c1d75
Show file tree
Hide file tree
Showing 7 changed files with 467 additions and 117 deletions.
10 changes: 6 additions & 4 deletions sre/io.janusproject/io.janusproject.network/META-INF/MANIFEST.MF
Expand Up @@ -4,18 +4,20 @@ Bundle-Name: %Bundle-Name
Bundle-SymbolicName: io.janusproject.network;singleton:=true
Bundle-Version: 0.12.0.qualifier
Bundle-Vendor: %Bundle-Vendor
Export-Package: io.sarl.sre.network,
io.sarl.sre.network.boot,
io.sarl.sre.network.services
Require-Bundle: io.sarl.core;bundle-version="0.12.0",
io.sarl.util;bundle-version="0.12.0",
io.sarl.util;bundle-version="0.12.0",
io.sarl.api.naming;bundle-version="0.12.0",
org.eclipse.osgi;bundle-version="3.15.100",
javax.inject;bundle-version="1.0.0",
io.bootique;bundle-version="1.0.0",
org.arakhne.afc.bootique.log4j;bundle-version="16.0.0",
org.arakhne.afc.bootique.variables;bundle-version="16.0.0",
com.google.inject;bundle-version="4.2.3",
com.hazelcast;bundle-version="4.0.0",
com.hazelcast;bundle-version="4.0.3",
io.janusproject.plugin;bundle-version="0.12.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Automatic-Module-Name: io.janusproject.network
Bundle-ActivationPolicy: lazy
Export-Package: io.sarl.sre.network.boot,
io.sarl.sre.network.services
@@ -1,3 +1,3 @@
io.sarl.sre.network.totoprovider
io.sarl.sre.network.NetworkModuleProvider


@@ -1,5 +1,56 @@
package io.sarl.sre.network

import com.google.inject.AbstractModule
import com.google.inject.Module
import com.google.inject.Provides
import com.hazelcast.core.Hazelcast
import com.hazelcast.core.HazelcastInstance
import io.bootique.BQModule
import io.bootique.BQModuleProvider
import io.sarl.sre.boot.internal.services.ContextServiceModule
import io.sarl.sre.network.services.HazelcastContextService
import io.sarl.sre.network.services.HazelcastEventTransportService
import io.sarl.sre.network.services.HazelcastSpaceRepository
import io.sarl.sre.services.context.ContextService
import io.sarl.sre.services.context.SpaceRepository
import io.sarl.sre.spaces.EventTransportService
import java.util.Collection
import javax.inject.Singleton

class NetworkModule extends AbstractModule {

protected override configure {
typeof(SpaceRepository).bind.to(typeof(HazelcastSpaceRepository))
typeof(ContextService).bind.to(typeof(HazelcastContextService)).in(typeof(Singleton))
typeof(EventTransportService).bind.to(typeof(HazelcastEventTransportService)).in(typeof(Singleton))

}

@Provides
@Singleton
def provideHazelcastInstance() : HazelcastInstance {
Hazelcast.newHazelcastInstance
}


}

class NetworkModuleProvider implements BQModuleProvider {

override module : Module {
return new NetworkModule
}

override moduleBuilder : BQModule.Builder {
return BQModule::builder(module).overrides(overrides).providerName(name).configs(configs).description(
"First version of SRE Network Module");
}

override overrides : Collection<Class<? extends Module>> {
#[ContextServiceModule]
}

}



@@ -1,18 +1,145 @@
package io.sarl.sre.network.services

import com.google.inject.Injector
import com.hazelcast.core.EntryEvent
import com.hazelcast.core.EntryListener
import com.hazelcast.core.HazelcastInstance
import com.hazelcast.map.IMap
import io.sarl.lang.core.SpaceID
import com.hazelcast.map.MapEvent
import io.sarl.lang.core.Agent
import io.sarl.sre.KernelScope
import io.sarl.sre.boot.configs.SreConfig
import io.sarl.sre.services.context.Context
import io.sarl.sre.services.context.ContextFactory
import io.sarl.sre.services.context.MemoryBasedContextService
import io.sarl.sre.services.logging.LoggingService
import java.util.UUID
import java.util.logging.Level
import java.util.logging.Logger
import javax.inject.Inject

class HazelcastContextService extends MemoryBasedContextService {

/**
* Local Hazelcast instance
*/
var hazelcastInstance : HazelcastInstance;

/**
* Map linking a context id to its associated default space id. This map must be
* distributed and synchronized all over the network
*/
var defaultSpaces: IMap<UUID, SpaceID>



var defaultSpaces : IMap<UUID, UUID>

/**
* ID of the listener defined on defaultSpaces map
*/
var defaultSpacesListenerID : UUID

/**
* SRE Kernel logger
*/
var kernelLogger : Logger;

@Inject
new(sreConfig : SreConfig, @KernelScope rootContext : Context, injector : Injector, factory : ContextFactory,
iHazelcastInstance : HazelcastInstance, distributedContextSpaceMapName : String, logger : LoggingService) {
super(rootContext, injector, factory)
hazelcastInstance = iHazelcastInstance
defaultSpaces = this.hazelcastInstance.getMap(sreConfig.boot.rootContextID.toString());

kernelLogger = logger.kernelLogger
}

protected def newContextInstance(contextID : UUID, defaultSpaceID : UUID, owner : Agent) : Context {
this.defaultSpaces.putIfAbsent(contextID, defaultSpaceID);

return super.newContextInstance(contextID, defaultSpaceID, owner)
}

override removeContext(contextID : UUID) : Context {
this.defaultSpaces.remove(contextID);
super.removeContext(contextID)
}

override onStart {
super.onStart
var defaultSpacesListerner = new EntryListener<UUID, UUID>() {

def entryAdded(^event : EntryEvent<UUID, UUID>) {
ensureDefaultSpaceDefinition(^event.key, ^event.value, null)
}

def entryUpdated(^event : EntryEvent<UUID, UUID>) {
//
}

def entryRemoved(^event : EntryEvent<UUID, UUID>) {
removeDefaultSpaceDefinition(^event.key, ^event.value)
}

def entryEvicted(^event : EntryEvent<UUID, UUID>) {
//
}

def entryExpired(^event : EntryEvent<UUID, UUID>) {
//
}

def mapCleared(^event : MapEvent) {
//
}

def mapEvicted(^event : MapEvent) {
//
}

}
defaultSpacesListenerID = defaultSpaces.addEntryListener(defaultSpacesListerner, true)
}

protected def ensureDefaultSpaceDefinition(contextID : UUID, defaultSpaceID : UUID, owner : Agent) {
kernelLogger.log(Level::INFO,
"Creating local space " + defaultSpaceID + " of the Context " + contextID + " following a network request")

if (getContext(contextID) === null) {
// Assuming the first request we got, is the one corresponding to the default space
super.createContext(contextID, defaultSpaceID, owner);
} else {
if (getContext(contextID).defaultSpace.spaceID.ID != defaultSpaceID) {
kernelLogger.log(Level::SEVERE,
"ERROR: Trying to create a local space" + defaultSpaceID +
" considered as the default space of the Context " + contextID +
" following a network request, but is is not")
}
}
}

protected def removeDefaultSpaceDefinition(contextID : UUID, defaultSpaceID : UUID) {
if (getContext(contextID).defaultSpace.isPseudoEmpty()) {

if (getContext(contextID).defaultSpace.spaceID.ID === defaultSpaceID) {

kernelLogger.log(Level::INFO,
"Removing local space " + defaultSpaceID + " of the Context " + contextID +
" following a network request")
super.removeContext(contextID)

} else {
kernelLogger.log(Level::SEVERE,
"ERROR: Trying to remove a local space" + defaultSpaceID +
" considered as the default space of the Context " + contextID +
" following a network request, but is is not")
}

}
}

override onStop {
super.onStop
// TODO check if it is really necessary to clean this distributed map of Contexts, because it will impact other kernels staying active on the network
defaultSpaces.clear
defaultSpaces.removeEntryListener(defaultSpacesListenerID)
}

}

0 comments on commit 50c1d75

Please sign in to comment.