alef 0.25.37

Opinionated polyglot binding generator for Rust libraries
Documentation
// ServerHandle allows stopping a service started via StartBackground.
type ServerHandle struct {
	service *{{ service_name }}
}

// Stop gracefully shuts down the server.
func (h *ServerHandle) Stop() error {
	if h.service == nil {
		return errors.New("service already stopped")
	}
	h.service.Close()
	h.service = nil
	return nil
}

// StartBackground starts the service in a background goroutine and returns a handle.
// It blocks until the TCP socket is bound, so the server is guaranteed to be accepting
// connections when this call returns.
func (s *{{ service_name }}) StartBackground(host string, port uint16) (*ServerHandle, error) {
	// Configure the service with the requested host and port before starting.
	hostPtr := host
	portPtr := port
	if err := s.Config(&ServerConfig{Host: &hostPtr, Port: &portPtr}); err != nil {
		return nil, err
	}

	// Lock to check ownership and then spawn Run in a goroutine.
	s.mu.Lock()
	if s.owner == nil {
		s.mu.Unlock()
		return nil, errors.New("service is closed")
	}
	s.mu.Unlock()

	// Spawn Run in a goroutine.
	go func() {
		_ = s.Run()
	}()

	// Poll TCP socket until it's bound or timeout (5 seconds).
	deadline := time.Now().Add(5 * time.Second)
	for time.Now().Before(deadline) {
		conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", host, port), 100*time.Millisecond)
		if err == nil {
			conn.Close()
			break
		}
		time.Sleep(50 * time.Millisecond)
	}

	// Return a handle for shutdown.
	return &ServerHandle{service: s}, nil
}