Golang离线文件处理与报表生成框架

Golang离线文件处理与报表生成框架 在我开始尝试构建自己的框架来实现这个功能之前,我想先问问是否已经有现成的解决方案。

我正在构建一个允许用户上传文件的Web应用程序,然后有一个后端系统离线处理文件并生成一些结果。处理时间可能从几秒到几小时不等,所以我希望用户能够离开,稍后再回来查看。

用户无需拥有账户即可上传文件,因此我无法仅仅在他们的账户中标记已完成的任务。

我希望能够给用户一个URL或令牌,他们可以用它来检查进度,理想情况下能与后端通信,询问它认为处理到了哪个阶段(百分比、剩余时间等)。

我还希望能够选择性地在上传时获取一个电子邮件地址,并在处理完成后通过邮件通知他们。

这样的功能,或者至少是其中的一部分,是否已经存在?


更多关于Golang离线文件处理与报表生成框架的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

这听起来更像是一个应用程序,而不是一个框架。

更多关于Golang离线文件处理与报表生成框架的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


好的,那么是否存在一个能实现此功能的应用程序呢?

这看起来非常庞大,学习起来复杂,可能有些过度设计。但看起来也很有趣,值得深入研究,并且为未来的扩展提供了充足的空间,所以我喜欢它。

快速浏览了一下,他们正在迁移到版本2并放弃对版本1的支持,所以我可能会尝试V2。我只是希望V1的文档仍然适用于V2,并且有向后兼容性,因为我不想在没有良好文档的情况下尝试弄清楚如何实现它。

GitHub头像

Issue: Is this repo still maintained?

计划在一个大型代码库中采用这个,但看到未解决的问题数量和最后一次提交… 有点担心。

GitHub头像

taylorchu/work

gocraft/work v2 原型。通过在 GitHub 上创建帐户来为 taylorchu/work 的开发做出贡献。

在Go生态中,确实有现成的解决方案可以组合实现这些需求。以下是几个关键组件和示例:

1. 任务队列与异步处理 推荐使用asynqmachinery

// 使用asynq示例
import "github.com/hibiken/asynq"

// 定义处理任务
func handleFileProcessing(ctx context.Context, t *asynq.Task) error {
    fileID := t.Payload().GetString("file_id")
    // 处理逻辑
    updateProgress(fileID, 50) // 更新进度
    return nil
}

// 创建任务
task := asynq.NewTask("process:file", 
    map[string]interface{}{"file_id": fileID})
client.Enqueue(task, asynq.ProcessIn(10*time.Second))

2. 进度跟踪 可以使用Redis存储进度信息:

// 进度管理结构
type ProgressTracker struct {
    redis *redis.Client
}

func (p *ProgressTracker) Update(fileToken string, percent int, eta time.Time) {
    data := map[string]interface{}{
        "percent": percent,
        "eta":     eta.Format(time.RFC3339),
        "updated": time.Now().Format(time.RFC3339),
    }
    p.redis.HSet(context.Background(), 
        "progress:"+fileToken, data)
}

func (p *ProgressTracker) Get(fileToken string) (map[string]string, error) {
    return p.redis.HGetAll(context.Background(), 
        "progress:"+fileToken).Result()
}

3. 无状态访问令牌 生成可验证的临时令牌:

import "github.com/google/uuid"
import "crypto/hmac"
import "crypto/sha256"

func GenerateToken(fileID string) string {
    token := uuid.New().String()
    // 使用HMAC签名确保令牌有效性
    h := hmac.New(sha256.New, []byte(secretKey))
    h.Write([]byte(fileID + ":" + token))
    signature := base64.URLEncoding.EncodeToString(h.Sum(nil))
    
    return base64.URLEncoding.EncodeToString(
        []byte(fmt.Sprintf("%s:%s:%s", fileID, token, signature)))
}

func ValidateToken(encoded string) (string, bool) {
    // 验证逻辑
    return fileID, valid
}

4. 邮件通知集成 使用gomail发送通知:

import "gopkg.in/gomail.v2"

func SendCompletionEmail(to, resultURL string) error {
    m := gomail.NewMessage()
    m.SetHeader("From", "noreply@example.com")
    m.SetHeader("To", to)
    m.SetHeader("Subject", "文件处理完成")
    m.SetBody("text/html", 
        fmt.Sprintf(`<a href="%s">查看结果</a>`, resultURL))
    
    d := gomail.NewDialer("smtp.example.com", 587, "user", "pass")
    return d.DialAndSend(m)
}

5. 完整的工作流示例

// 上传处理端点
func UploadHandler(w http.ResponseWriter, r *http.Request) {
    file, header, _ := r.FormFile("file")
    email := r.FormValue("email")
    
    // 生成唯一标识
    fileID := uuid.New().String()
    token := GenerateToken(fileID)
    
    // 保存文件
    saveFile(fileID, file)
    
    // 创建异步任务
    task := asynq.NewTask("process:file", map[string]interface{}{
        "file_id": fileID,
        "token":   token,
        "email":   email,
    })
    client.Enqueue(task)
    
    // 返回检查URL
    json.NewEncoder(w).Encode(map[string]string{
        "check_url": fmt.Sprintf("/status/%s", token),
        "token":     token,
    })
}

// 状态检查端点
func StatusHandler(w http.ResponseWriter, r *http.Request) {
    token := r.PathValue("token")
    fileID, valid := ValidateToken(token)
    if !valid {
        http.Error(w, "Invalid token", http.StatusBadRequest)
        return
    }
    
    progress, _ := tracker.Get(fileID)
    json.NewEncoder(w).Encode(progress)
}

现有框架参考:

  • asynq:Redis-based任务队列
  • machinery:分布式任务队列
  • gocelery:Celery风格的分布式任务系统
  • go-workers:Sidekiq兼容的工作队列

这些组件可以组合构建出你描述的系统。虽然没有单一的"开箱即用"框架,但这些库提供了完整的构建模块。

回到顶部