|
| 1 | +package main |
| 2 | + |
| 3 | +import ( |
| 4 | + "time" |
| 5 | + |
| 6 | + "go.uber.org/cadence/workflow" |
| 7 | + "go.uber.org/cadence/x/blocks" |
| 8 | + "go.uber.org/zap" |
| 9 | +) |
| 10 | + |
| 11 | +/** |
| 12 | + * This is the blocks workflow sample that demonstrates JSON blob queries. |
| 13 | + */ |
| 14 | + |
| 15 | +// ApplicationName is the task list for this sample |
| 16 | +const ApplicationName = "blocksGroup" |
| 17 | + |
| 18 | +const blocksWorkflowName = "blocksWorkflow" |
| 19 | + |
| 20 | +// This is an example of using the 'blocks' query response in a cadence query, in this example, |
| 21 | +// to select the lunch option. |
| 22 | +func blocksWorkflow(ctx workflow.Context, name string) error { |
| 23 | + ao := workflow.ActivityOptions{ |
| 24 | + ScheduleToStartTimeout: time.Minute, |
| 25 | + StartToCloseTimeout: time.Minute, |
| 26 | + HeartbeatTimeout: time.Second * 20, |
| 27 | + } |
| 28 | + ctx = workflow.WithActivityOptions(ctx, ao) |
| 29 | + |
| 30 | + logger := workflow.GetLogger(ctx) |
| 31 | + |
| 32 | + votes := []map[string]string{} |
| 33 | + |
| 34 | + workflow.SetQueryHandler(ctx, "options", func() (blocks.QueryResponse, error) { |
| 35 | + logger := workflow.GetLogger(ctx) |
| 36 | + logger.Info("Responding to 'options' query") |
| 37 | + |
| 38 | + return makeResponse(votes), nil |
| 39 | + }) |
| 40 | + |
| 41 | + votesChan := workflow.GetSignalChannel(ctx, "lunch_order") |
| 42 | + workflow.Go(ctx, func(ctx workflow.Context) { |
| 43 | + for { |
| 44 | + var vote map[string]string |
| 45 | + votesChan.Receive(ctx, &vote) |
| 46 | + votes = append(votes, vote) |
| 47 | + } |
| 48 | + }) |
| 49 | + defer func() { |
| 50 | + votesChan.Close() |
| 51 | + }() |
| 52 | + |
| 53 | + err := workflow.Sleep(ctx, 30*time.Minute) |
| 54 | + if err != nil { |
| 55 | + logger.Error("Sleep failed", zap.Error(err)) |
| 56 | + return err |
| 57 | + } |
| 58 | + |
| 59 | + logger.Info("Workflow completed.", zap.Any("Result", votes)) |
| 60 | + return nil |
| 61 | +} |
| 62 | + |
| 63 | +// makeResponse creates the lunch query response payload based on the current votes |
| 64 | +func makeResponse(votes []map[string]string) blocks.QueryResponse { |
| 65 | + return blocks.New( |
| 66 | + blocks.NewMarkdownSection("## Lunch options\nWe're voting on where to order lunch today. Select the option you want to vote for."), |
| 67 | + blocks.NewDivider(), |
| 68 | + blocks.NewMarkdownSection(makeVoteTable(votes)), |
| 69 | + blocks.NewMarkdownSection(makeMenu()), |
| 70 | + blocks.NewSignalActions( |
| 71 | + blocks.NewSignalButton("Farmhouse", "lunch_order", map[string]string{"location": "farmhouse - red thai curry", "requests": "spicy"}), |
| 72 | + blocks.NewSignalButtonWithExternalWorkflow("Ethiopian", "no_lunch_order_walk_in_person", nil, "in-person-order-workflow", ""), |
| 73 | + blocks.NewSignalButton("Ler Ros", "lunch_order", map[string]string{"location": "Ler Ros", "meal": "tofo Bahn Mi"}), |
| 74 | + ), |
| 75 | + ) |
| 76 | +} |
| 77 | + |
| 78 | +func makeMenu() string { |
| 79 | + |
| 80 | + options := []struct { |
| 81 | + image string |
| 82 | + desc string |
| 83 | + }{ |
| 84 | + { |
| 85 | + image: "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e2/Red_roast_duck_curry.jpg/200px-Red_roast_duck_curry.jpg", |
| 86 | + desc: "Farmhouse - Red Thai Curry: (Thai: แกง, romanized: kaeng, pronounced [kɛ̄ːŋ]) is a dish in Thai cuisine made from curry paste, coconut milk or water, meat, seafood, vegetables or fruit, and herbs. Curries in Thailand mainly differ from the Indian subcontinent in their use of ingredients such as fresh rhizomes, herbs, and aromatic leaves rather than a mix of dried spices.", |
| 87 | + }, |
| 88 | + { |
| 89 | + image: "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0c/B%C3%A1nh_m%C3%AC_th%E1%BB%8Bt_n%C6%B0%E1%BB%9Bng.png/200px-B%C3%A1nh_m%C3%AC_th%E1%BB%8Bt_n%C6%B0%E1%BB%9Bng.png", |
| 90 | + desc: "Ler Ros: Lemongrass Tofu Bahn Mi: In Vietnamese cuisine, bánh mì, bánh mỳ or banh mi is a sandwich consisting of a baguette filled with various ingredients, most commonly including a protein such as pâté, chicken, or pork, and vegetables such as lettuce, cilantro, and cucumber.", |
| 91 | + }, |
| 92 | + { |
| 93 | + image: "https://upload.wikimedia.org/wikipedia/commons/thumb/5/54/Ethiopian_wat.jpg/960px-Ethiopian_wat.jpg", |
| 94 | + desc: "Ethiopian Wat: Wat is a traditional Ethiopian dish made from a mixture of spices, vegetables, and legumes. It is typically served with injera, a sourdough flatbread that is used to scoop up the food.", |
| 95 | + }, |
| 96 | + } |
| 97 | + |
| 98 | + table := "| Picture | Description |\n|---|----|\n" |
| 99 | + for _, option := range options { |
| 100 | + table += "|  | " + option.desc + " |\n" |
| 101 | + } |
| 102 | + |
| 103 | + table += "\n\n\n(source wikipedia)" |
| 104 | + |
| 105 | + return table |
| 106 | +} |
| 107 | + |
| 108 | +func makeVoteTable(votes []map[string]string) string { |
| 109 | + if len(votes) == 0 { |
| 110 | + return "| lunch order vote | meal | requests |\n|-------|-------|-------|\n| No votes yet |\n" |
| 111 | + } |
| 112 | + table := "| lunch order vote | meal | requests |\n|-------|-------|-------|\n" |
| 113 | + for _, vote := range votes { |
| 114 | + |
| 115 | + loc := vote["location"] |
| 116 | + meal := vote["meal"] |
| 117 | + requests := vote["requests"] |
| 118 | + |
| 119 | + table += "| " + loc + " | " + meal + " | " + requests + " |\n" |
| 120 | + } |
| 121 | + |
| 122 | + return table |
| 123 | +} |
0 commit comments