# Service.go

```go
package core

import (
	"sync"
	"time"
)

type Timer struct {
	start time.Time
}

func NewTimer() *Timer {
	return &Timer{start: time.Now()}
}

func (t *Timer) LastInterval() time.Duration {
	return time.Since(t.start)
}

func (t *Timer) Check() {
	t.start = time.Now()
}

type Service struct {
	args      map[string]string
	routine   []Routine
	pointer   int
	queue     chan func()
	iterate   time.Duration
	queueWait sync.WaitGroup
}

type Routine struct {
	function func()
	timer    *Timer
	ucycle   time.Duration
}

func NewService() *Service {
	return &Service{
		args:    make(map[string]string),
		routine: []Routine{},
		queue:   make(chan func(), 100), // Buffered channel to handle tasks
		iterate: time.Millisecond * 100,
	}
}

func (s *Service) SetArgs(args map[string]string) {
	s.args = args
}

func (s *Service) GetArgs() map[string]string {
	return s.args
}

func (s *Service) Init() {
	// Override to provide initialization logic
}

func (s *Service) Main() {
	s.TaskRoutine()
	s.TaskQueue()
	s.Iterate()
}

func (s *Service) Iterate() {
	time.Sleep(s.iterate)
}

func (s *Service) TaskRoutine() {
	if len(s.routine) == 0 {
		return
	}

	if s.pointer >= len(s.routine) {
		s.pointer = 0
	}

	routine := s.routine[s.pointer]
	s.pointer++

	if time.Since(routine.timer.start) > routine.ucycle {
		routine.function()
		routine.timer.Check()
	}
}

func (s *Service) TaskQueue() {
	select {
	case task := <-s.queue:
		if task != nil {
			task()
		}
	default:
	}
}

func (s *Service) AddRoutine(function func(), ucycle time.Duration) {
	s.routine = append(s.routine, Routine{
		function: function,
		timer:    NewTimer(),
		ucycle:   ucycle,
	})
}

func (s *Service) AddQueue(task func()) {
	s.queueWait.Add(1)
	s.queue <- func() {
		defer s.queueWait.Done()
		task()
	}
}

func (s *Service) WaitQueue() {
	s.queueWait.Wait()
}
```

#### Timer 구조체와 메서드

`Timer`는 시간 측정에 사용됩니다.

1. **NewTimer 함수**

   ```go
   func NewTimer() *Timer {
       return &Timer{start: time.Now()}
   }
   ```

   * **역할**: 새로운 `Timer` 객체를 생성합니다.
   * **동작 방식**: 현재 시간을 `start` 필드에 저장하고 `Timer` 객체를 반환합니다.<br>
2. **LastInterval 메서드**

   ```go
   func (t *Timer) LastInterval() time.Duration {
       return time.Since(t.start)
   }
   ```

   * **역할**: 타이머가 시작된 이후 경과된 시간을 반환합니다.
   * **동작 방식**: `time.Since` 함수를 사용하여 `start` 이후 경과된 시간을 계산하여 반환합니다.<br>
3. **Check 메서드**

   ```go
   func (t *Timer) Check() {
       t.start = time.Now()
   }
   ```

   * **역할**: 타이머를 재설정합니다.
   * **동작 방식**: 현재 시간을 `start` 필드에 다시 저장합니다.

#### Service 구조체와 메서드

`Service`는 주기적으로 실행되는 작업(routine)과 큐에 저장된 작업(queue)을 관리합니다.

1. **NewService 함수**

   ```go
   func NewService() *Service {
       return &Service{
           args:    make(map[string]string),
           routine: []Routine{},
           queue:   make(chan func(), 100),
           iterate: time.Millisecond * 100,
       }
   }
   ```

   * **역할**: 새로운 `Service` 객체를 생성합니다.
   * **동작 방식**: `args`, `routine`, `queue`를 초기화하고, `iterate` 주기를 설정한 `Service` 객체를 반환합니다.<br>
2. **SetArgs 메서드**

   ```go
   func (s *Service) SetArgs(args map[string]string) {
       s.args = args
   }
   ```

   * **역할**: 서비스의 인자를 설정합니다.
   * **동작 방식**: 인자로 받은 `args` 맵을 `args` 필드에 할당합니다.<br>
3. **GetArgs 메서드**

   ```go
   func (s *Service) GetArgs() map[string]string {
       return s.args
   }
   ```

   * **역할**: 서비스의 인자를 반환합니다.
   * **동작 방식**: `args` 필드를 반환합니다.<br>
4. **Init 메서드**

   ```go
   func (s *Service) Init() {
       // Override to provide initialization logic
   }
   ```

   * **역할**: 서비스 초기화 로직을 정의합니다. 이 메서드는 서브클래스에서 오버라이드되어 구체적인 초기화 로직을 추가할 수 있습니다.<br>
5. **Main 메서드**

   ```go
   func (s *Service) Main() {
       s.TaskRoutine()
       s.TaskQueue()
       s.Iterate()
   }
   ```

   * **역할**: 서비스의 주 작업 루프를 정의합니다.
   * **동작 방식**:
     * `TaskRoutine`: 주기적으로 실행되는 작업을 처리합니다.
     * `TaskQueue`: 큐에 저장된 작업을 처리합니다.
     * `Iterate`: 반복 주기를 기다립니다.<br>
6. **Iterate 메서드**

   ```go
   func (s *Service) Iterate() {
       time.Sleep(s.iterate)
   }
   ```

   * **역할**: 반복 주기 동안 대기합니다.
   * **동작 방식**: `time.Sleep`을 사용하여 `iterate` 필드에 지정된 시간만큼 대기합니다.<br>
7. **TaskRoutine 메서드**

   ```go
   func (s *Service) TaskRoutine() {
       if len(s.routine) == 0 {
           return
       }

       if s.pointer >= len(s.routine) {
           s.pointer = 0
       }

       routine := s.routine[s.pointer]
       s.pointer++

       if time.Since(routine.timer.start) > routine.ucycle {
           routine.function()
           routine.timer.Check()
       }
   }
   ```

   * **역할**: 주기적으로 실행되는 작업을 처리합니다.
   * **동작 방식**:
     * `pointer`가 가리키는 작업을 가져와 실행 주기가 지났는지 확인합니다.
     * 실행 주기가 지났으면 해당 작업을 실행하고 타이머를 재설정합니다.
     * 다음 작업으로 포인터를 이동합니다.<br>
8. **TaskQueue 메서드**

   ```go
   func (s *Service) TaskQueue() {
       select {
       case task := <-s.queue:
           if task != nil {
               task()
           }
       default:
       }
   }
   ```

   * **역할**: 큐에 저장된 작업을 처리합니다.
   * **동작 방식**: 큐에서 작업을 가져와 실행합니다. 큐가 비어 있으면 아무 작업도 하지 않습니다.<br>
9. **AddRoutine 메서드**

   ```go
   func (s *Service) AddRoutine(function func(), ucycle time.Duration) {
       s.routine = append(s.routine, Routine{
           function: function,
           timer:    NewTimer(),
           ucycle:   ucycle,
       })
   }
   ```

   * **역할**: 새로운 주기 작업을 추가합니다.
   * **동작 방식**: 주기 작업을 `routine` 리스트에 추가합니다. 작업에는 함수와 실행 주기(`ucycle`), 타이머가 포함됩니다.<br>
10. **AddQueue 메서드**

    ```go
    func (s *Service) AddQueue(task func()) {
        s.queueWait.Add(1)
        s.queue <- func() {
            defer s.queueWait.Done()
            task()
        }
    }
    ```

    * **역할**: 큐에 새로운 작업을 추가합니다.
    * **동작 방식**:
      * 작업을 큐에 추가합니다.
      * 작업이 완료되면 `WaitGroup` 카운터를 감소시킵니다.<br>
11. **WaitQueue 메서드**

    ```go
    func (s *Service) WaitQueue() {
        s.queueWait.Wait()
    }
    ```

    * **역할**: 큐에 있는 모든 작업이 완료될 때까지 대기합니다.
    * **동작 방식**: `WaitGroup`을 사용하여 모든 큐 작업이 완료될 때까지 대기합니다.

#### 요약

이 코드는 주기적으로 실행되는 작업(routine)과 큐에 저장된 작업(queue)을 관리하는 서비스 시스템을 구현합니다. 각 작업은 주기적으로 실행되거나 큐에서 꺼내져 실행됩니다. `Service` 구조체는 작업을 관리하고 실행하는 데 필요한 다양한 메서드를 제공합니다.
