mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-04 23:16:37 +08:00
refactor(core): align architecture with cordis spatiotemporal composability
This commit is contained in:
@@ -278,3 +278,44 @@ func TestContextExtensionPointsIntegration(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, eventReceived)
|
||||
}
|
||||
|
||||
func TestExtensionPointsUnregister(t *testing.T) {
|
||||
ctx := core.NewContext(context.Background())
|
||||
|
||||
// 1. Router unregister
|
||||
rd := ctx.Router().GET("/temp", "temp_handler")
|
||||
assert.Greater(t, rd.ID, uint64(0))
|
||||
assert.Len(t, ctx.Router().Routes(), 1)
|
||||
assert.True(t, ctx.Router().Unregister("GET", "/temp"))
|
||||
assert.Len(t, ctx.Router().Routes(), 0)
|
||||
|
||||
rd2 := ctx.Router().POST("/temp2", "temp2_handler")
|
||||
assert.Len(t, ctx.Router().Routes(), 1)
|
||||
assert.True(t, ctx.Router().UnregisterByID(rd2.ID))
|
||||
assert.Len(t, ctx.Router().Routes(), 0)
|
||||
|
||||
// 2. Task unregister
|
||||
ctx.Task().Register("temp:task", "handler")
|
||||
assert.Len(t, ctx.Task().Tasks(), 1)
|
||||
assert.True(t, ctx.Task().Unregister("temp:task"))
|
||||
assert.Len(t, ctx.Task().Tasks(), 0)
|
||||
|
||||
// 3. Schedule unregister
|
||||
ctx.Schedule().RegisterCron("@hourly", "temp:cron", nil)
|
||||
assert.Len(t, ctx.Schedule().Schedules(), 1)
|
||||
assert.True(t, ctx.Schedule().Unregister("temp:cron"))
|
||||
assert.Len(t, ctx.Schedule().Schedules(), 0)
|
||||
|
||||
// 4. Setting unregister
|
||||
ctx.Settings().Register(extpoints.SettingSchema{Key: "temp.key", Default: 1})
|
||||
assert.Len(t, ctx.Settings().Schemas(), 1)
|
||||
assert.True(t, ctx.Settings().Unregister("temp.key"))
|
||||
assert.Len(t, ctx.Settings().Schemas(), 0)
|
||||
|
||||
// 5. Migration unregister
|
||||
fsys := fstest.MapFS{"001.sql": &fstest.MapFile{Data: []byte("-- migration")}}
|
||||
ctx.Migrations().Register("temp_plugin", fsys)
|
||||
assert.Len(t, ctx.Migrations().Entries(), 1)
|
||||
assert.True(t, ctx.Migrations().Unregister("temp_plugin"))
|
||||
assert.Len(t, ctx.Migrations().Entries(), 0)
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ type MigrationExtension interface {
|
||||
Register(pluginID string, fsys fs.FS, dir ...string)
|
||||
Entries() []MigrationEntry
|
||||
Get(pluginID string) (MigrationEntry, bool)
|
||||
Unregister(pluginID string) bool
|
||||
}
|
||||
|
||||
// MigrationRegistry collects and stores migration entries from plugins.
|
||||
@@ -69,6 +70,25 @@ func (m *MigrationRegistry) Register(pluginID string, fsys fs.FS, dir ...string)
|
||||
m.lookup[pluginID] = entry
|
||||
}
|
||||
|
||||
// Unregister removes a registered migration entry by plugin ID.
|
||||
func (m *MigrationRegistry) Unregister(pluginID string) bool {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
if _, exists := m.lookup[pluginID]; !exists {
|
||||
return false
|
||||
}
|
||||
|
||||
delete(m.lookup, pluginID)
|
||||
for i, e := range m.entries {
|
||||
if e.PluginID == pluginID {
|
||||
m.entries = append(m.entries[:i], m.entries[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Entries returns a copy of all registered migration entries in registration order.
|
||||
func (m *MigrationRegistry) Entries() []MigrationEntry {
|
||||
m.mu.RLock()
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
// RouteDefinition holds the metadata and handler list for a single HTTP route.
|
||||
type RouteDefinition struct {
|
||||
ID uint64
|
||||
Method string
|
||||
Path string
|
||||
Handlers []any
|
||||
@@ -31,11 +32,14 @@ type RouterExtension interface {
|
||||
Any(path string, handlers ...any) []RouteDefinition
|
||||
Routes() []RouteDefinition
|
||||
Middlewares() []any
|
||||
Unregister(method, path string) bool
|
||||
UnregisterByID(id uint64) bool
|
||||
}
|
||||
|
||||
// RouterRegistry implements RouterExtension as the root route and middleware collector.
|
||||
type RouterRegistry struct {
|
||||
mu sync.RWMutex
|
||||
nextID uint64
|
||||
routes []RouteDefinition
|
||||
middlewares []any
|
||||
}
|
||||
@@ -75,7 +79,9 @@ func (r *RouterRegistry) Handle(method, path string, handlers ...any) RouteDefin
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
r.nextID++
|
||||
rd := RouteDefinition{
|
||||
ID: r.nextID,
|
||||
Method: strings.ToUpper(method),
|
||||
Path: cleanPath(path),
|
||||
Handlers: handlers,
|
||||
@@ -85,6 +91,37 @@ func (r *RouterRegistry) Handle(method, path string, handlers ...any) RouteDefin
|
||||
return rd
|
||||
}
|
||||
|
||||
// Unregister removes a route matching method and path from the registry.
|
||||
func (r *RouterRegistry) Unregister(method, path string) bool {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
targetMethod := strings.ToUpper(method)
|
||||
targetPath := cleanPath(path)
|
||||
|
||||
for i, rd := range r.routes {
|
||||
if rd.Method == targetMethod && rd.Path == targetPath {
|
||||
r.routes = append(r.routes[:i], r.routes[i+1:]...)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// UnregisterByID removes a route by its unique ID.
|
||||
func (r *RouterRegistry) UnregisterByID(id uint64) bool {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
for i, rd := range r.routes {
|
||||
if rd.ID == id {
|
||||
r.routes = append(r.routes[:i], r.routes[i+1:]...)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// GET registers a GET route.
|
||||
func (r *RouterRegistry) GET(path string, handlers ...any) RouteDefinition {
|
||||
return r.Handle("GET", path, handlers...)
|
||||
@@ -176,7 +213,9 @@ func (g *RouterGroup) Handle(method, path string, handlers ...any) RouteDefiniti
|
||||
allMiddlewares = append(allMiddlewares, g.registry.middlewares...)
|
||||
allMiddlewares = append(allMiddlewares, g.middlewares...)
|
||||
|
||||
g.registry.nextID++
|
||||
rd := RouteDefinition{
|
||||
ID: g.registry.nextID,
|
||||
Method: strings.ToUpper(method),
|
||||
Path: fullPath,
|
||||
Handlers: handlers,
|
||||
@@ -186,6 +225,17 @@ func (g *RouterGroup) Handle(method, path string, handlers ...any) RouteDefiniti
|
||||
return rd
|
||||
}
|
||||
|
||||
// Unregister removes a route under this group prefix matching method and path.
|
||||
func (g *RouterGroup) Unregister(method, path string) bool {
|
||||
fullPath := joinPaths(g.prefix, path)
|
||||
return g.registry.Unregister(method, fullPath)
|
||||
}
|
||||
|
||||
// UnregisterByID removes a route by its unique ID.
|
||||
func (g *RouterGroup) UnregisterByID(id uint64) bool {
|
||||
return g.registry.UnregisterByID(id)
|
||||
}
|
||||
|
||||
// GET registers a GET route in this group.
|
||||
func (g *RouterGroup) GET(path string, handlers ...any) RouteDefinition {
|
||||
return g.Handle("GET", path, handlers...)
|
||||
|
||||
@@ -32,6 +32,7 @@ type ScheduleExtension interface {
|
||||
RegisterCron(spec string, taskType string, payload any, opts ...ScheduleOption)
|
||||
Schedules() []ScheduleDefinition
|
||||
Get(taskType string) (ScheduleDefinition, bool)
|
||||
Unregister(taskType string) bool
|
||||
}
|
||||
|
||||
// ScheduleRegistry collects and manages schedule registrations.
|
||||
@@ -85,6 +86,25 @@ func (s *ScheduleRegistry) RegisterCron(spec string, taskType string, payload an
|
||||
s.Register(spec, taskType, payload, opts...)
|
||||
}
|
||||
|
||||
// Unregister removes a registered schedule definition by its task type.
|
||||
func (s *ScheduleRegistry) Unregister(taskType string) bool {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if _, exists := s.lookup[taskType]; !exists {
|
||||
return false
|
||||
}
|
||||
|
||||
delete(s.lookup, taskType)
|
||||
for i, item := range s.schedules {
|
||||
if item.TaskType == taskType {
|
||||
s.schedules = append(s.schedules[:i], s.schedules[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Schedules returns a copy of all registered ScheduleDefinitions.
|
||||
func (s *ScheduleRegistry) Schedules() []ScheduleDefinition {
|
||||
s.mu.RLock()
|
||||
|
||||
@@ -22,6 +22,7 @@ type SettingExtension interface {
|
||||
Register(schema SettingSchema)
|
||||
Schemas() []SettingSchema
|
||||
Get(key string) (SettingSchema, bool)
|
||||
Unregister(key string) bool
|
||||
}
|
||||
|
||||
// SettingRegistry collects and manages setting configuration schemas.
|
||||
@@ -62,6 +63,25 @@ func (s *SettingRegistry) Register(schema SettingSchema) {
|
||||
s.lookup[schema.Key] = schema
|
||||
}
|
||||
|
||||
// Unregister removes a registered SettingSchema by its key.
|
||||
func (s *SettingRegistry) Unregister(key string) bool {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if _, exists := s.lookup[key]; !exists {
|
||||
return false
|
||||
}
|
||||
|
||||
delete(s.lookup, key)
|
||||
for i, item := range s.schemas {
|
||||
if item.Key == key {
|
||||
s.schemas = append(s.schemas[:i], s.schemas[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Schemas returns a copy of all registered SettingSchemas.
|
||||
func (s *SettingRegistry) Schemas() []SettingSchema {
|
||||
s.mu.RLock()
|
||||
|
||||
@@ -57,6 +57,7 @@ type TaskExtension interface {
|
||||
Register(pattern string, handler any, opts ...TaskOption)
|
||||
Tasks() []TaskDefinition
|
||||
Get(pattern string) (TaskDefinition, bool)
|
||||
Unregister(pattern string) bool
|
||||
}
|
||||
|
||||
// TaskRegistry collects and manages task registrations.
|
||||
@@ -104,6 +105,25 @@ func (t *TaskRegistry) Register(pattern string, handler any, opts ...TaskOption)
|
||||
t.lookup[pattern] = td
|
||||
}
|
||||
|
||||
// Unregister removes a registered task definition by its pattern.
|
||||
func (t *TaskRegistry) Unregister(pattern string) bool {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
if _, exists := t.lookup[pattern]; !exists {
|
||||
return false
|
||||
}
|
||||
|
||||
delete(t.lookup, pattern)
|
||||
for i, item := range t.tasks {
|
||||
if item.Pattern == pattern {
|
||||
t.tasks = append(t.tasks[:i], t.tasks[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Tasks returns a copy of all registered TaskDefinitions.
|
||||
func (t *TaskRegistry) Tasks() []TaskDefinition {
|
||||
t.mu.RLock()
|
||||
|
||||
Reference in New Issue
Block a user