Skip to content

Commit

Permalink
feat: updates
Browse files Browse the repository at this point in the history
  • Loading branch information
hokamsingh committed Aug 24, 2024
1 parent 70f0df6 commit f159175
Show file tree
Hide file tree
Showing 9 changed files with 474 additions and 66 deletions.
21 changes: 19 additions & 2 deletions internal/core/concurrency/concurrency.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,29 @@ type Task struct {
fn TaskFunc
}

// NewTask creates a new Task.
// TaskFunc defines the type for the task function that returns a result and an error.
// @callback TaskFunc
// @param {context.Context} ctx - The context for the task, used for cancellation and deadlines.
// @returns {interface{}, error} The result of the task and an error, if any.
//
// Example:
//
// taskFunc := func(ctx context.Context) (interface{}, error) {
// return "task result", nil
// }
func NewTask(fn TaskFunc) *Task {
return &Task{fn: fn}
}

// Execute runs the task function and returns the result or an error.
// Example:
//
// result, err := task.Execute(context.Background())
// if err != nil {
// log.Fatal(err)
// }
//
// fmt.Println(result)
func (t *Task) Execute(ctx context.Context) (interface{}, error) {
return t.fn(ctx)
}
Expand All @@ -28,7 +45,7 @@ type ExecutionMode int

const (
Parallel ExecutionMode = 0
Sequential ExecutionMode = 1
Sequential ExecutionMode = 1
)

// TaskManager manages and executes tasks concurrently or sequentially.
Expand Down
33 changes: 33 additions & 0 deletions internal/core/config/config.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
/*
Package config provides functionality to load and manage application configuration
from environment variables and .env files.
The package leverages the `godotenv` package to load environment variables from a `.env` file into
the application, allowing easy configuration management.
Usage:
import "your/package/path/config"
func main() {
cfg := config.LoadConfig()
port := cfg.Get("PORT", "8080")
// Use the `port` variable...
}
*/
package config

import (
Expand All @@ -8,8 +25,16 @@ import (
"github.com/joho/godotenv"
)

// Config represents a map of configuration key-value pairs loaded from the environment.
type Config map[string]string

// LoadConfig loads environment variables into a Config map. It first attempts to load a `.env` file
// using the `godotenv` package. If no `.env` file is found, it logs a message but continues to load
// environment variables from the system.
// Example:
//
// cfg := config.LoadConfig()
// fmt.Println(cfg["PORT"])
func LoadConfig() Config {
if err := godotenv.Load(); err != nil {
log.Printf("No .env file found: %v", err)
Expand All @@ -27,6 +52,14 @@ func LoadConfig() Config {
return config
}

// Get retrieves a value from the Config map based on the provided key. If the key does not exist
// in the Config, the function returns the specified default value.
//
// Example:
//
// cfg := config.LoadConfig()
// port := cfg.Get("PORT", "8080")
// fmt.Println("Server will run on port:", port)
func (c Config) Get(key, defaultValue string) string {
if value, exists := c[key]; exists {
return value
Expand Down
38 changes: 37 additions & 1 deletion internal/core/controller/controller.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,52 @@
/*
Package controller provides a base structure and interface for defining and registering routes in the application.
This package defines the Controller interface that all controllers must implement to register their routes,
as well as a BaseController struct that provides a default implementation of the interface.
*/
package controller

import (
"github.com/hokamsingh/lessgo/internal/core/router"
)

// BASE
// Controller defines the interface that all controllers in the application must implement.
// Any controller that implements this interface must define the RegisterRoutes method,
// which is responsible for setting up the necessary routes for the controller.
type Controller interface {
RegisterRoutes(r *router.Router)
}

// BaseController provides a default implementation of the Controller interface.
// It can be embedded in other controllers to inherit its default behavior,
// or overridden with custom implementations.
type BaseController struct{}

// RegisterRoutes is the default implementation of the Controller interface's method.
// This method can be overridden by embedding BaseController in another struct
// and defining a custom implementation.
//
// Example
//
// type TestController struct {
// LessGo.BaseController
// Path string
// Service TestService
// }
//
// func NewTestController(service *TestService, path string) *TestController {
// return &TestController{
// Service: *service,
// Path: path,
// }
// }
//
// func (tc *TestController) RegisterRoutes(r *LessGo.Router) {
// tr := r.SubRouter(tc.Path)
// tr.Get("/ping", func(ctx *LessGo.Context) {
// ctx.Send("pong")
// })
// }
func (bc *BaseController) RegisterRoutes(r *router.Router) {

}
160 changes: 103 additions & 57 deletions internal/core/di/di.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,49 @@
/*
Package di provides a simple Dependency Injection (DI) container using the `dig` library.
This package defines a `Container` struct that wraps the `dig.Container` and provides methods for registering and invoking dependencies. It also includes specialized methods for registering and invoking a scheduler within the DI container.
Usage:
import (
"log"
"github.com/hokamsingh/lessgo/pkg/lessgo/di"
"github.com/hokamsingh/lessgo/pkg/lessgo/scheduler"
)
func main() {
// Create a new DI container
container := di.NewContainer()
// Register dependencies
if err := container.RegisterScheduler(); err != nil {
log.Fatalf("Error registering scheduler: %v", err)
}
// Invoke a function with the scheduler dependency
err := container.InvokeScheduler(func(sched scheduler.Scheduler) error {
// Add a job to the scheduler
if err := sched.AddJob("@every 1m", func() {
log.Println("Job running every minute")
}); err != nil {
return err
}
// Start the scheduler
sched.Start()
// Stop the scheduler when the application shuts down
defer sched.Stop()
return nil
})
if err != nil {
log.Fatalf("Error invoking scheduler: %v", err)
}
// Start your application logic here
}
*/
package di

import (
Expand All @@ -7,88 +53,88 @@ import (
"go.uber.org/dig"
)

// Container wraps the `dig.Container` and provides methods for registering and invoking dependencies.
// This struct serves as the main entry point for setting up and managing dependency injection within the application.
type Container struct {
container *dig.Container
}

// NewContainer creates a new instance of `Container`.
// This method initializes the underlying `dig.Container`.
//
// Example:
//
// container := di.NewContainer()
func NewContainer() *Container {
return &Container{
container: dig.New(),
}
}

// Register adds a constructor or provider to the DI container.
// This method allows you to register dependencies that can later be resolved and injected where needed.
//
// Example:
//
// container := di.NewContainer()
// err := container.Register(func() MyService {
// return NewMyService()
// })
func (c *Container) Register(constructor interface{}) error {
return c.container.Provide(constructor)
}

// // Provide is an alias for Register. It registers a constructor or provider in the container
// func (c *Container) Provide(constructor interface{}) error {
// return c.Register(constructor)
// }

// Invoke resolves dependencies and invokes the specified function.
// This method allows you to execute a function with its dependencies automatically injected by the container.
//
// Example:
//
// container := di.NewContainer()
// err := container.Invoke(func(svc MyService) {
// svc.DoSomething()
// })
func (c *Container) Invoke(function interface{}) error {
return c.container.Invoke(function)
}

/*
RegisterScheduler sets up and registers the scheduler in the DI container.
This method ensures that the scheduler is available for dependency injection within your LessGo application. It uses the `cron` package under the hood to provide scheduling capabilities.
### Example Usage
```go
package main
import (
"log"
"github.com/hokamsingh/lessgo/pkg/lessgo"
"github.com/hokamsingh/lessgo/pkg/lessgo/scheduler"
)
func main() {
// Create a new DI container
container := lessgo.NewContainer()
// Register the scheduler in the container
if err := container.RegisterScheduler(); err != nil {
log.Fatalf("Error registering scheduler: %v", err)
}
// Use the scheduler
err := container.InvokeScheduler(func(sched scheduler.Scheduler) error {
// Add a job to the scheduler
if err := sched.AddJob("@every 1m", func() {
log.Println("Job running every minute")
}); err != nil {
return err
}
// Start the scheduler
sched.Start()
// Optionally, stop the scheduler when your application shuts down
defer sched.Stop()
return nil
})
if err != nil {
log.Fatalf("Error invoking scheduler: %v", err)
}
// Start your application logic here
}
*/
// RegisterScheduler sets up and registers the scheduler in the DI container.
// This method ensures that the scheduler is available for dependency injection within your LessGo application.
//
// Example:
//
// container := di.NewContainer()
// err := container.RegisterScheduler()
// if err != nil {
// log.Fatalf("Error registering scheduler: %v", err)
// }
func (c *Container) RegisterScheduler() error {
sched := scheduler.NewCronScheduler()
return c.Register(func() scheduler.Scheduler {
return sched
})
}

// InvokeScheduler provides access to the scheduler for initialization or configuration
// InvokeScheduler provides access to the scheduler for initialization or configuration.
// This method invokes a function that takes the scheduler as a parameter, allowing you to configure it.
//
// Example:
//
// container := di.NewContainer()
// err := container.RegisterScheduler()
// if err != nil {
// log.Fatalf("Error registering scheduler: %v", err)
// }
//
// err = container.InvokeScheduler(func(sched scheduler.Scheduler) error {
// // Configure the scheduler
// return sched.AddJob("@hourly", func() {
// log.Println("Job running every hour")
// })
// })
//
// if err != nil {
// log.Fatalf("Error invoking scheduler: %v", err)
// }
func (c *Container) InvokeScheduler(fn func(scheduler.Scheduler) error) error {
return c.container.Invoke(func(sched scheduler.Scheduler) {
if err := fn(sched); err != nil {
Expand Down
Loading

0 comments on commit f159175

Please sign in to comment.