diff --git a/manager/app/appmanager.go b/manager/app/appmanager.go index 0e31f5d..70b2505 100644 --- a/manager/app/appmanager.go +++ b/manager/app/appmanager.go @@ -211,7 +211,7 @@ func (AM *AppManagerStruct) Shutdown(safe bool) error { // if err != nil { // log.Fatalf("Failed to create local manager: %v", err) // } -func (AM *AppManagerStruct) NewLocalManager(localName string) (*interfaces.LocalGoroutineManagerInterface, error) { +func (AM *AppManagerStruct) NewLocalManager(localName string) (interfaces.LocalGoroutineManagerInterface, error) { startTime := time.Now() defer func() { duration := time.Since(startTime) @@ -230,7 +230,7 @@ func (AM *AppManagerStruct) NewLocalManager(localName string) (*interfaces.Local return nil, err } - return &localManager, nil + return localManager, nil } // GetAllLocalManagers retrieves all local managers registered with this app manager. diff --git a/manager/global/globalmanager.go b/manager/global/globalmanager.go index 7c9b241..deacaad 100644 --- a/manager/global/globalmanager.go +++ b/manager/global/globalmanager.go @@ -439,3 +439,28 @@ func (GM *GlobalManagerStruct) GetMetadata() (*types.Metadata, error) { func (GM *GlobalManagerStruct) Get() (*types.GlobalManager, error) { return types.GetGlobalManager() } + +// NewAppManager creates a new app manager within the global manager. +// This method is used to create a new app manager within the global manager. +// +// Parameters: +// - appName: The name of the app manager to create +// +// Returns: +// - *interfaces.AppGoroutineManagerInterface: The created app manager instance +// - error: Returns error if app manager creation fails or if not found +// +// Example: +// +// appMgr, err := globalMgr.NewAppManager("test-app") +// if err != nil { +// log.Fatalf("Failed to create app manager: %v", err) +// } +func (GM *GlobalManagerStruct) NewAppManager(appName string) (interfaces.AppGoroutineManagerInterface, error) { + AppManager := app.NewAppManager(appName) + _, err := AppManager.CreateApp() + if err != nil { + return nil, err + } + return AppManager, nil +} diff --git a/manager/interfaces/interfaces.go b/manager/interfaces/interfaces.go index b03009f..6793126 100644 --- a/manager/interfaces/interfaces.go +++ b/manager/interfaces/interfaces.go @@ -19,7 +19,7 @@ type GlobalInitializer interface { Get() (*types.GlobalManager, error) } -// Functions to get the +// Functions to get the type Shutdowner interface { Shutdown(safe bool) error } @@ -119,6 +119,8 @@ type GlobalGoroutineManagerInterface interface { LocalManagerLister GoroutineLister + + NewAppManager(appName string) (AppGoroutineManagerInterface, error) } // AppGoroutineManagerInterface defines the complete interface for app manager @@ -132,6 +134,9 @@ type AppGoroutineManagerInterface interface { GoroutineLister LocalManagerGetter + + // NewLocalManager creates a new local manager within this app manager + NewLocalManager(localName string) (LocalGoroutineManagerInterface, error) } // LocalGoroutineManagerInterface defines the complete interface for local manager diff --git a/test/manager/appmanager_test.go b/test/manager/appmanager_test.go index 569c10e..a379577 100644 --- a/test/manager/appmanager_test.go +++ b/test/manager/appmanager_test.go @@ -42,6 +42,92 @@ func TestAppManager_CreateApp(t *testing.T) { } } +func TestCreateLocalManager(t *testing.T) { + common.ResetGlobalState() + + globalMgr := global.NewGlobalManager() + + // Create app manager first time + AppManager1, err := globalMgr.NewAppManager("test-app") + if err != nil { + t.Fatalf("NewAppManager() failed: %v", err) + } + + // Create local manager first time + LocalManager1, err := AppManager1.NewLocalManager("test-local") + if err != nil { + t.Fatalf("NewLocalManager() failed: %v", err) + } + + if LocalManager1 == nil { + t.Fatal("NewLocalManager() returned nil") + } + + // Create the same app manager again + AppManager2, err := globalMgr.NewAppManager("test-app") + if err != nil { + t.Fatalf("NewAppManager() second call failed: %v", err) + } + + // Create the same local manager again + LocalManager2, err := AppManager2.NewLocalManager("test-local") + if err != nil { + t.Fatalf("NewLocalManager() second call failed: %v", err) + } + + if LocalManager2 == nil { + t.Fatal("NewLocalManager() second call returned nil") + } + + // Verify interface instances are different (new structs created each time) + // But they should manage the same underlying state + if AppManager1 == AppManager2 { + t.Error("AppManager instances should be different (new structs created each time)") + } + + if LocalManager1 == LocalManager2 { + t.Error("LocalManager interface instances should be different (new structs created each time)") + } + + // Verify they point to the same underlying state by checking the types + // Get the underlying types.LocalManager instances + app1, err := AppManager1.Get() + if err != nil { + t.Fatalf("AppManager1.Get() failed: %v", err) + } + + app2, err := AppManager2.Get() + if err != nil { + t.Fatalf("AppManager2.Get() failed: %v", err) + } + + // Both should point to the same *types.AppManager instance + if app1 != app2 { + t.Error("AppManager1 and AppManager2 should point to the same underlying *types.AppManager instance") + } + + // Verify local managers point to the same underlying state + local1, err := LocalManager1.Get() + if err != nil { + t.Fatalf("LocalManager1.Get() failed: %v", err) + } + + local2, err := LocalManager2.Get() + if err != nil { + t.Fatalf("LocalManager2.Get() failed: %v", err) + } + + // Both should point to the same *types.LocalManager instance + if local1 != local2 { + t.Error("LocalManager1 and LocalManager2 should point to the same underlying *types.LocalManager instance") + } + + // Verify they have the same properties (since they're the same instance, this is redundant but good for clarity) + if local1.LocalName != local2.LocalName { + t.Errorf("LocalName mismatch: %s != %s", local1.LocalName, local2.LocalName) + } +} + func TestAppManager_CreateApp_Idempotent(t *testing.T) { common.ResetGlobalState()