ouqiang/gocron
定时任务管理系统
Stale — last commit 2y ago
weakest axislast commit was 2y ago; no tests detected…
no tests detected; no CI workflows detected…
Documented and popular — useful reference codebase to read through.
last commit was 2y ago; no CI workflows detected
- ✓8 active contributors
- ✓MIT licensed
- ⚠Stale — last commit 2y ago
Show all 6 evidence items →Show less
- ⚠Single-maintainer risk — top contributor 87% of recent commits
- ⚠No CI workflows detected
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Mixed → Healthy if: 1 commit in the last 365 days; add a test suite
- →Fork & modify Mixed → Healthy if: add a test suite
- →Deploy as-is Mixed → Healthy if: 1 commit in the last 180 days
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Great to learn from" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/ouqiang/gocron)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/ouqiang/gocron on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: ouqiang/gocron
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/ouqiang/gocron shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Stale — last commit 2y ago
- 8 active contributors
- MIT licensed
- ⚠ Stale — last commit 2y ago
- ⚠ Single-maintainer risk — top contributor 87% of recent commits
- ⚠ No CI workflows detected
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live ouqiang/gocron
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/ouqiang/gocron.
What it runs against: a local clone of ouqiang/gocron — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in ouqiang/gocron | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 801 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of ouqiang/gocron. If you don't
# have one yet, run these first:
#
# git clone https://github.com/ouqiang/gocron.git
# cd gocron
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of ouqiang/gocron and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "ouqiang/gocron(\\.git)?\\b" \\
&& ok "origin remote is ouqiang/gocron" \\
|| miss "origin remote is not ouqiang/gocron (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "cmd/gocron/gocron.go" \\
&& ok "cmd/gocron/gocron.go" \\
|| miss "missing critical file: cmd/gocron/gocron.go"
test -f "cmd/node/node.go" \\
&& ok "cmd/node/node.go" \\
|| miss "missing critical file: cmd/node/node.go"
test -f "internal/models/task.go" \\
&& ok "internal/models/task.go" \\
|| miss "missing critical file: internal/models/task.go"
test -f "internal/routers/routers.go" \\
&& ok "internal/routers/routers.go" \\
|| miss "missing critical file: internal/routers/routers.go"
test -f "internal/modules/rpc/proto/task.proto" \\
&& ok "internal/modules/rpc/proto/task.proto" \\
|| miss "missing critical file: internal/modules/rpc/proto/task.proto"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 801 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~771d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/ouqiang/gocron"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
gocron is a lightweight, web-based distributed task scheduler written in Go that replaces Linux crontab functionality. It provides a Macaron-based HTTP API and web UI (Vue.js frontend) to manage scheduled jobs across multiple worker nodes via gRPC, supporting shell commands and HTTP requests with cron expressions precise to the second, retry logic, timeout enforcement, and task dependencies. Monolithic Go binary with split architecture: cmd/gocron is the scheduler/webserver, cmd/node is the worker agent. Core logic in internal/models/ (task, task_log, task_host models using xorm ORM), internal/modules/ contains service layers (httpclient, notify, rpc client/server with gRPC pool). Frontend in Vue.js (76KB) likely in a separate build artifact. Config via app.ini, runs on MySQL backend.
👥Who it's for
DevOps engineers and SREs managing scheduled jobs across multiple servers who need a centralized web UI alternative to crontab; system administrators wanting job execution visibility, notification integration (email/Slack/Webhook), and multi-user access control without setting up complex distributed systems.
🌱Maturity & risk
Production-ready and actively maintained. The project has explicit version releases, comprehensive feature set including HTTPS support and multi-user permissions, proper ORM integration via xorm, and structured logging. Last visible updates show maturity (v1.5+ releases mentioned), though the Go module version (go 1.12) indicates the codebase is several years old and may lack modern Go idioms.
Moderate maintenance risk: single author (ouqiang) maintains the core, with dated dependencies (xorm 0.7.1, Macaron 1.3.2 from ~2019, no recent Go version bumps visible). The gRPC pool implementation in internal/modules/rpc/grpcpool/ could be a bottleneck. Protobuf generation (task.proto → task.pb.go) requires manual regeneration. No visible CI/CD pipeline or automated tests in the file structure.
Active areas of work
The repo shows completed features from the TODO (batch operations, HTTPS support, task groups, multi-user, permissions) but no visible active development commits in the provided data. The delay-queue functionality was spun into a separate project, indicating some architectural evolution. Current state appears stable rather than actively developed.
🚀Get running
git clone https://github.com/ouqiang/gocron.git
cd gocron
export GO111MODULE=on
make
# Start scheduler: ./bin/gocron web
# Start worker: ./bin/gocron-node
# Web UI: http://localhost:5920
# For development: make install-vue && make run-vue (requires Node.js, Yarn)
Daily commands:
Scheduler: ./gocron web --host 0.0.0.0 -p 5920 -e dev (flags: -e for env, -p for port). Worker: ./gocron-node -s 0.0.0.0:5921 (flags: -enable-tls, -ca-file, -cert-file, -key-file for HTTPS). Development: make run starts both, make run-vue (npm/yarn) starts dev frontend on port 8080 with API proxy to scheduler.
🗺️Map of the codebase
cmd/gocron/gocron.go— Main entry point for the scheduler service; initializes the application, database, routers, and RPC server.cmd/node/node.go— Entry point for the task execution agent node; handles shell task execution and RPC communication with scheduler.internal/models/task.go— Core Task model defining the database schema and task attributes; foundation for all task operations.internal/routers/routers.go— Main router configuration file that wires all HTTP endpoints for the web API.internal/modules/rpc/proto/task.proto— gRPC protocol buffer definition for task communication between scheduler and agent nodes.internal/service/task.go— Core business logic layer for task execution, scheduling, and inter-task dependencies.internal/modules/app/app.go— Application singleton that manages global state including database connection, settings, and logger.
🛠️How to make changes
Add a new HTTP API endpoint
- Create a new router file in internal/routers/{resource}/ or add to existing file (e.g., internal/routers/task/task.go) (
internal/routers/task/task.go) - Add the router handler method and register it in internal/routers/routers.go using the Macaron framework (
internal/routers/routers.go) - Implement business logic in internal/service/task.go or create a new service file (
internal/service/task.go) - Use the database models in internal/models/ to persist data via xorm ORM (
internal/models/task.go)
Add a new task notification type
- Create a new notifier file in internal/modules/notify/ (e.g., notify_sms.go) (
internal/modules/notify/notify.go) - Implement the notifier interface and register it in the dispatcher in internal/modules/notify/notify.go (
internal/modules/notify/notify.go) - Add configuration fields to the task model in internal/models/task.go if needed (
internal/models/task.go)
Add a new task type (beyond shell and HTTP)
- Add new task type constant to internal/models/task.go and extend the Task model if needed (
internal/models/task.go) - Implement execution logic in internal/service/task.go for the new task type (
internal/service/task.go) - For non-HTTP tasks, extend the gRPC service in internal/modules/rpc/proto/task.proto and regenerate .pb.go files (
internal/modules/rpc/proto/task.proto) - Update cmd/node/node.go to handle execution of the new task type (
cmd/node/node.go)
Add a new page to the web UI
- Create a new Vue component in web/vue/src/ directory (
web/vue/src/App.vue) - Create corresponding HTTP API endpoint in internal/routers/ directory (
internal/routers/base/base.go) - Add routing configuration in web/vue to connect the new component to a URL path (
web/vue/src/App.vue)
🔧Why these technologies
- Go + Macaron web framework — Lightweight, fast compiled binary for distributed task scheduling; Macaron provides simple but complete web framework with middleware support
- MySQL + xorm ORM — Reliable persistent storage for task definitions and execution logs; xorm provides cross-platform database abstraction
- gRPC + Protocol Buffers — Efficient binary protocol for task dispatch to remote agent nodes with strong typing and schema versioning
- Vue.js frontend — Reactive UI for real-time task management and monitoring; single-page application reduces server load
- crontab expressions — Familiar scheduling syntax for users migrating from Linux cron; widely understood and supported
⚖️Trade-offs already made
-
Scheduler polls database for task scheduling rather than using in-memory job queue
- Why: Allows scheduler to be restarted without losing task state; multiple scheduler instances can coexist by using database as single source of truth
- Consequence: Database query overhead on polling interval; eventual consistency delay in task execution (typically seconds)
-
Agent nodes pull tasks via gRPC rather than scheduler pushing tasks
- Why: Agents can operate behind firewalls; no need for reverse connectivity from scheduler to agents
- Consequence: Agent latency depends on polling interval; scheduler has less direct control over agent execution timing
-
Single monolithic scheduler process vs. distributed task queue (Kafka/RabbitMQ)
- Why: Simpler deployment and operational model; eliminates external dependency on message broker for small to medium deployments
- Consequence: Single point of failure for scheduling (though stateless can be mitigated); does not scale to millions of tasks like enterprise systems
-
Web UI embeds in same process as scheduler (via statik) rather than separate SPA deployment
- Why: Single binary deployment; no frontend build complexity in production
- Consequence: UI changes require recompiling and redeploying scheduler; tight coupling between backend API and frontend versions
🚫Non-goals (don't propose these)
- Real-time task execution (cron is second-level precision, not millisecond)
- Distributed consensus or scheduler high-availability out-of-the-box (requires external load balancer and coordination)
- Support for arbitrary programming languages in task nodes (only shell commands and HTTP
🪤Traps & gotchas
MySQL required: No SQLite fallback; app.ini must point to valid MySQL connection or startup fails. Database migrations: xorm auto-migration in migration.go must run before any task queries; version mismatches cause cryptic ORM errors. Protobuf regeneration: task.pb.go is committed; editing task.proto requires running protoc manually—no build step enforces this. gRPC pool: internal/modules/rpc/grpcpool has no visible max-connections or timeout configuration; worker overload could hang scheduler. TLS for gocron-node: gocron web connects via HTTP by default; inter-node auth requires manual cert provisioning (no auto-generation). Config path: app.ini path is hardcoded or environment-dependent; deployment often fails due to missing config discovery. No graceful shutdown: Neither gocron nor gocron-node appear to have SIGTERM handlers visible in cmd/ files.
🏗️Architecture
💡Concepts to learn
- Cron Expression — gocron's core scheduling primitive (6-field cron expressions with second precision); job timing entirely depends on parsing and evaluating these expressions via the jakecoffman/cron library
- gRPC and Protocol Buffers — Scheduler-to-worker communication uses gRPC (task.proto defines the service contract); understanding protobuf serialization and gRPC connection pooling is critical for distributed task execution
- Connection Pooling — internal/modules/rpc/grpcpool/grpc_pool.go manages persistent gRPC connections to worker nodes; poor pooling causes task dispatch bottlenecks in multi-worker setups
- Task Dependency Graph — Task model supports job dependencies (A completes before B runs); requires topological ordering and execution planning visible in internal/models/task.go
- ORM (Object-Relational Mapping) — xorm ORM abstracts MySQL queries in internal/models/*.go; all CRUD operations go through xorm struct tags and session builders rather than raw SQL
- JWT (JSON Web Tokens) — Authentication uses dgrijalva/jwt-go for stateless user sessions; internal/modules/rpc/auth handles token validation between scheduler and worker nodes
- Webhook Pattern — Task execution results trigger webhooks (internal/modules/notify/webhook.go); gocron acts as a webhook client posting job outcomes to external systems
🔗Related repos
ouqiang/delay-queue— Official companion project extracted from gocron to handle delayed tasks separately; users managing both cron and delayed job queues need both reposrobfig/cron— Direct upstream dependency (github.com/jakecoffman/cron used instead but same concept); understanding cron expression parsing helps with task scheduling logicgo-xorm/xorm— Core ORM dependency; gocron's data access layer built entirely on xorm, queries in models/*.go rely on xorm syntaxgo-macaron/macaron— Web framework used for HTTP API and routing; cmd/gocron/gocron.go uses Macaron exclusively for request handlingofqyang/gocron-admin— Community fork/sibling frontend project that may have alternate UI implementations or deployment patterns useful for understanding the scheduler architecture
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add unit tests for internal/modules/utils/utils.go
The utils package contains critical utility functions but only has a minimal test file (utils_test.go). Given that utils.go has platform-specific variants (utils_unix.go, utils_windows.go) and the repo depends on utilities for cross-platform task scheduling, comprehensive tests are essential for reliability. This would improve code coverage and catch regressions in core functionality used across the scheduler.
- [ ] Review existing tests in internal/modules/utils/utils_test.go
- [ ] Identify untested functions in utils.go, utils_unix.go, and utils_windows.go
- [ ] Add unit tests covering platform-specific behavior (Unix vs Windows path handling, process management)
- [ ] Test edge cases for JSON utility functions in json.go
- [ ] Run tests across multiple platforms to validate cross-platform compatibility
Add integration tests for internal/modules/rpc/ (gRPC client-server)
The RPC module (internal/modules/rpc/) is critical for distributed task execution across nodes, with components for authentication (auth/), client communication (client/), connection pooling (grpcpool/), and protobuf definitions (proto/). Currently, there appear to be no integration tests validating the gRPC communication flow, authentication handshake, or connection pooling behavior. This is high-risk given its role in task distribution.
- [ ] Create integration test file at internal/modules/rpc/rpc_integration_test.go
- [ ] Write tests for gRPC server startup and client connection (internal/modules/rpc/server/server.go and client/client.go)
- [ ] Test authentication flow in internal/modules/rpc/auth/Certification.go
- [ ] Validate connection pool behavior (grpcpool/grpc_pool.go) under concurrent load
- [ ] Test protobuf message serialization for task execution (task.proto/task.pb.go)
Add GitHub Actions CI workflow for multi-platform builds and tests
The project supports multiple platforms (Unix/Windows with separate utils files) and uses gRPC with protobuf, but there's no visible CI configuration. Given the cross-platform nature and the presence of a Dockerfile, automated testing on Linux, Windows, and macOS (if applicable) would catch platform-specific bugs early. This is especially important for a scheduler managing distributed tasks.
- [ ] Create .github/workflows/test.yml for running Go tests on Linux, Windows, and macOS
- [ ] Include protobuf compilation validation (go-grpc generation from task.proto)
- [ ] Add Docker image build verification using Dockerfile and Dockerfile.release
- [ ] Test against Go 1.12 (from go.mod) and recent versions
- [ ] Configure workflow to run on pull requests and merges to catch regressions
🌿Good first issues
- Add unit tests for internal/modules/utils/utils.go—only utils_test.go exists but likely incomplete coverage for JSON encoding/decoding and utility functions used throughout the codebase: No test coverage visible for critical utility functions; helps prevent regressions in core helpers
- Document gRPC connection pooling behavior and add configuration options to internal/modules/rpc/grpcpool/grpc_pool.go (max connections, timeout, retry logic): grpc_pool.go has no visible configuration or documentation; production deployments need tuning knobs to prevent scheduler-to-worker bottlenecks
- Add structured logging middleware to log all HTTP requests/responses in cmd/gocron/gocron.go using logrus, matching the logger module in internal/modules/logger/: Debugging task dispatch issues requires visibility into scheduler HTTP/gRPC calls; current seelog config lacks structured request logging
⭐Top contributors
Click to expand
Top contributors
- @ouqiang — 87 commits
- @zhmin — 4 commits
- @chaiyd — 2 commits
- @EamonZhang — 2 commits
- @zhangqiusheng — 2 commits
📝Recent commits
Click to expand
Recent commits
960fc98— Update Dockerfile (chaiyd)7a949a2— Update Dockerfile (chaiyd)c59f8b7— added remark for notify (yangyin5127)ac2f01f— 修改 当后端使用postgres数据库时 修改任务或用户状态报错问题。postgres字段区分大小写。 (EamonZhang)09834ff— 修改后端使用postgres时,任务关闭/打开 错误 (EamonZhang)93c544f— bugfix#编辑任务节点,主机名变更可能导致所有任务定时器被重置 (ouqiang)9f9c663— Merge branch 'master' of github.com:ouqiang/gocron (ouqiang)beeda4b— bugfix#map可能会出现并发读写 (ouqiang)fc7daa8— Update README.md (ouqiang)9215153— Merge branch 'master' of github.com:ouqiang/gocron (ouqiang)
🔒Security observations
- Critical · Outdated and Vulnerable Dependencies —
go.mod, Dockerfile (golang:1.15-alpine). The project uses Go 1.12 with dependencies from 2019 or earlier. Many have known vulnerabilities: dgrijalva/jwt-go (v3.2.0) has security issues, golang.org/x/crypto and golang.org/x/net are outdated, and google.golang.org/grpc (v1.21.0) has multiple CVEs. The go.mod shows no security patches applied. Fix: Update to Go 1.20+, audit and update all dependencies to latest stable versions. Rungo get -u ./...andgo mod tidy. Implement automated dependency scanning with tools like Dependabot or Snyk. - Critical · SQL Injection Vulnerability Risk —
internal/models/*, internal/service/task.go. The project uses go-xorm (v0.7.1) which is outdated and prone to SQL injection if raw queries are used. The presence of files like internal/models/task.go, internal/models/user.go suggest database interactions. No evidence of parameterized queries or ORM safety patterns visible in file structure. Fix: Ensure all database queries use parameterized queries/prepared statements. Audit codebase for raw SQL queries. Update xorm to xorm-core or use modern ORM like GORM with latest versions. - High · JWT Implementation Vulnerability —
go.mod (dgrijalva/jwt-go), internal/modules/rpc/auth/Certification.go. Using dgrijalva/jwt-go v3.2.0 which has known security vulnerabilities in token validation. This library is no longer maintained and has algorithm confusion vulnerabilities. Fix: Migrate to github.com/golang-jwt/jwt v4.0+. Review authentication logic in Certification.go for proper algorithm validation and token claims verification. - High · Insufficient Input Validation —
internal/routers/*, web/vue/. Web interface receives user input through HTTP handlers (internal/routers/) with binding via go-macaron/binding (v0.0.0-20170611065819). No visible input sanitization or validation framework indicates potential XSS and injection vulnerabilities. Fix: Implement strict input validation for all user inputs. Use parameterized templates, sanitize outputs. Apply CSP headers. Validate and sanitize data at both frontend and backend. - High · Missing Security Headers in Web Framework —
internal/modules/app/app.go, internal/routers/routers.go. Using macaron v1.3.2 (outdated, 2018). No evidence of security middleware for HSTS, X-Frame-Options, X-Content-Type-Options, CSP headers in the configuration. Fix: Add security middleware implementing HSTS, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, CSP headers. Consider upgrading to modern framework or using security middleware packages. - High · RPC Authentication Weakness —
internal/modules/rpc/auth/Certification.go, internal/modules/rpc/server/server.go. Custom RPC authentication in internal/modules/rpc/auth/Certification.go with JWT. No visible rate limiting, token expiration validation, or secure secret management patterns. Fix: Implement token expiration validation, rate limiting on authentication endpoints, secure secret storage (use environment variables/vaults). Add request signing and TLS for gRPC. - High · HTTP Client Security Issues —
internal/modules/httpclient/http_client.go, internal/modules/notify/webhook.go. internal/modules/httpclient/http_client.go likely makes external HTTP requests for webhooks and notifications without visible TLS verification, timeout controls, or input validation on URLs. Fix: Enforce TLS verification, implement request timeouts, validate and sanitize URLs before requests. Use allow-list for webhook destinations. Implement rate limiting for outbound requests. - Medium · Hardcoded Configuration Risk — ``. Docker container uses hardcoded timezone (Asia/Shanghai) and the Dockerfile clones from GitHub without pinning to a specific commit/tag, risking supply chain attacks. Fix: undefined
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.