Giter Club home page Giter Club logo

cadence-web's Introduction

Cadence Web UI

Build Status Docker Status

Cadence is a distributed, scalable, durable, and highly available orchestration engine we developed at Uber Engineering to execute asynchronous long-running business logic in a scalable and resilient way.

This web UI is used to view workflows from Cadence, see what's running, and explore and debug workflow executions.

Demo Usage

Getting Started

Configuration

Set these environment variables if you need to change their defaults

Variable Description Default
CADENCE_TCHANNEL_PEERS Comma-delmited list of tchannel peers 127.0.0.1:7933
CADENCE_TCHANNEL_SERVICE Name of the cadence tchannel service to call cadence-frontend
CADENCE_WEB_PORT HTTP port to serve on 8088
CADENCE_EXTERNAL_SCRIPTS Addtional JavaScript tags to serve in the UI
ENABLE_AUTH Enable auth feature false
AUTH_TYPE concurrently supports ADMIN_JWT ''
AUTH_ADMIN_JWT_PRIVATE_KEY JWT signing private key for ADMIN_JWT type ''

Running locally

cadence-web requires node v10.22.1 or greater to be able to run correctly. cadence-web uses all the standard npm scripts to install dependencies, run the server, and run tests.

To provide a consistent environment we recommend using docker in development. We provide a default configuration for remote containers using docker-compose.

Using VSCode Dev Containers

  1. Set up the Remote Containers plugin in VSCode.
  2. Open the cadence-web directory in VSCode.
  3. Use the Command Palette to select the 'Reopen folder in Container' option. npm install should run automatically in the container upon doing so.
  4. Run the app in the container with npm run dev.
  5. Open localhost:8088 (or the custom Cadence Web port you have defined) to load the webapp.

Using docker-compose to start the dev container

To start local server with live reload on code change you can run docker-compose up.

For development and contributing to cadence-web, please see the contributing guide.

You may also use docker by pulling ubercadence/web. It is also included in the Cadence server's local docker setup.

API

If you need to extend cadence-web to add middleware to the server, you can install cadence-web as a dependecy, and it will export the Koa web server that has not yet been started or configured. It includes an additional init function that will then compose the built-in middleware. This gives you an option to add middleware before or after you call init so it will add the middleware at the beginning or the end of the chain, respectively.

init(options)

All options are optional.

useWebpack: If true, starts webpack and adds the middleware, otherwise if false, it assumes the UI bundle was already built and serves it statically. Defaults to process.env.NODE_ENV === 'production'.

logErrors: If true, thrown errors are logged to console.error. Defaults to true.

For example, here is how you would add a request count metric using uber-statsd-client:

var app = require('cadence-web');
var createStatsd = require('uber-statsd-client');
var sdc = createStatsd({
  host: 'statsd.example.com',
});

app
  .use(async function(ctx, next) {
    sdc.increment('http.request');
    await next();
  })
  .init()
  .listen(7000);

The webpack configuration is also exported as webpackConfig, and can be modified before calling init().

Licence

MIT License, please see LICENSE for details.

cadence-web's People

Contributors

3vilhamster avatar adhityamamallan avatar assem-hafez avatar assem-uber avatar dmetzgar avatar gazi-yestemirova avatar just-at-uber avatar longquanzheng avatar mantas-sidlauskas avatar mindaugasbarcauskas avatar nathanboktae avatar sokada1221 avatar vancexu avatar vytautas-karpavicius avatar wtoma avatar yux0 avatar yycptt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cadence-web's Issues

Confusing Parent workflow info in summary page

image
It is confusing to show <current workflow type> - parent workflow id
For example, PARENT WORKFLOW of this workflow shows:
external - cron.workflow.sanity/workflow.sanity-9/workflow.cancellation

Should be parent workflow type - parent workflow id or just parent workflow id

Expose domain information

Domain has some configuration parameters that are currently exposed only through API/CLI:

cadence --env staging --do cadence-canary d desc
Name:cadence-canary, Description:Domain for cadence canaries, OwnerEmail:[email protected], Status:REGISTERED, RetentionInDays:7, EmitMetrics:true

Query workflow does not allow query arguments

When querying a workflow at the command line it is possible to pass arguments. For example

cadence --ct 100 --do my-domain --env prod wf query --workflow_id my-workflow-id --query_type my-query-type --input 2

But from the UI this is not possible as the following screenshot shows.

Screen Shot 2020-01-07 at 11 52 28 AM

Ideally from the web UI users should be able to pass arguments to their query handler. As a first pass I think the users should just get a free from text box where they can type JSON.

Timeout error on polling for history clears existing page

When viewing the history of a workflow it seems the code is polling for new events with a request like so:

https://cadence-staging.uberinternal.com/api/domain/emobility/workflows/UUIDHERE/history?waitForNewEvent=true&nextPageToken=TOKENHERE

This seems to return a 500 with the following body: {"message":"timeout"}

When this 500 is received, the existing history is cleared and a simple "timeout" error is shown, which makes it hard to use the tool.

What should happen is the XHR should be retried with no change to the UI.

Represent large integer values in UI

Large integer values (> 10e17) appear to lose precision in the UI.
I'm currently using the ubercadence/web:2.4.1 image.
For example, this DeviceID is passed to the worker as 321588685835436831 but appears as 321588685835436800
screen shot 2018-07-13 at 2 50 50 pm

Show sampled workflows

With the new feature to support long retention for sampled workflows (uber/cadence#1141), users should be able to filter to only workflow ids that were sampled for long retention. The sample is determined by hashing the workflow id and comparing a portion of the hash to a sample threshold. The same may be possible client side if the hash algorithm is the same.

UI breaks when accessing child workflows

After clicking on child workflows in compact view under history, UI breaks(mix of parent workflow activities and child workflow activities are shown) and web page needs to be refreshed to show correct data. Earlier this worked fine.

Our team used to see the activity start time, completion time also in the compact view , that's no longer provided. It'll be great to have that.

When listing workflows show result of a query in a column

It is very useful to be able to see a list of workflows with the correspondent statuses.
It can be done by emitting a query to a workflow execution for each member of the list. As listing is paginated it shouldn't increase latency too much. If it does then the status should be loaded asynchronously after the list is already rendered.

Trim leading/trailing spaces from workflow ID/Name filters

One thing I commonly do is copy the workflow name from the name column in the table and paste it into the search. Mysteriously, this produces no results. It takes a while to figure out that there are trailing spaces. Since these spaces should not be there in workflow IDs and names, the web UI could trim them.

Activities in compact view don't show the pointer cursor

Since v3.6.0, activities in the compact view stopped showing the pointer cursor. This could be confusing for new users since the activities are meant to be clickable in order to expose their details.

How to reproduce

  • Go to history page
  • Enable compact mode
  • Hover one of the listed activities found on the left sidebar

Export history contained base64 encoded firstDecisionCompletedId

History exported from UI has base64 encoded value for firstDecisionCompletedId
for example:

[ 
   { 
      "eventId":1,
      "timestamp":1572983709126469187,
      "eventType":"WorkflowExecutionStarted",
      "version":300,
      "taskId":446074314,
      "workflowExecutionStartedEventAttributes":{ 
         "workflowType":{ 
            "name":"PointTierAggregationWorkflow"
         },
         "taskList":{ 
            "name":"fx-worker-lunacore-0"
         },
         "input":"some dummy context g==",
         "executionStartToCloseTimeoutSeconds":864000,
         "taskStartToCloseTimeoutSeconds":10,
         "continuedExecutionRunId":"3f5a7b60-0e8d-4278-9d28-f5173b18f164",
         "originalExecutionRunId":"0de4c876-6592-4eba-b021-8dd3ec8854b3",
         "identity":"",
         "firstExecutionRunId":"bc0034d5-03c1-492e-b353-4a4a3cc4ae2c",
         "attempt":0,
         "prevAutoResetPoints":{ 
            "points":[ 
               { 
                  "binaryChecksum":"51c5b8b69ddba7aa6f967f6af63cbd6c",
                  "runId":"19343c17-a3c2-4cbe-8a15-5154c7cfe5ed",
                  "firstDecisionCompletedId":"AAAAAAAAAAQ=",
                  "createdTimeNano":1562702097534937255,
                  "expiringTimeNano":1564516497557519770,
                  "resettable":true
               },
               { 
                  "binaryChecksum":"277938d0d643a212cb7a152954abc8f3",
                  "runId":"19343c17-a3c2-4cbe-8a15-5154c7cfe5ed",
                  "firstDecisionCompletedId":"AAAAAAAAAAw=",
                  "createdTimeNano":1563306897557479300,
                  "expiringTimeNano":1564516497557519770,
                  "resettable":true
               },
               ......
            ]
         },
         "header":{ 
            "fields":{ 

            }
         }
      }
   },
   { 
      "eventId":2,
      "timestamp":1572983709126505634,
      "eventType":"DecisionTaskScheduled",
      "version":300,
      "taskId":446074315,
      "decisionTaskScheduledEventAttributes":{ 
         "taskList":{ 
            "name":"fx-worker-lunacore-0"
         },
         "startToCloseTimeoutSeconds":10,
         "attempt":0
      }
   },
   ...
]

Using such file directly in reply test will caused error:
cannot unmarshal string into Go struct field ResetPointInfo.firstDecisionCompletedId of type int64

UI exported history should be same as CLI output:
cadence --do domain wf show -w <wid> -r <rid> --output_filename history.json

Document docker hub repo name

I searched docker hub for the repo, but could not find it. I was assuming uber/cadence-web but no luck. Would be nice for the README to have this info.

Fix table headers

In both workflow list and execution history, fixing the table headers so they float as the user scrolls would be a better user experience.

History: Table performance is poor with thousands of rows

When history is huge (~4000 events and large payload), current cadence client GetWorkflowHistory tasks long time (> 5 min) to return result.
As a result, UI freeze and looks like not responding before getting the result.

We need to add support to use long poll with pagination.

Expose an URL with only the workflow-id which redirects to the currently running workflow

Cadence UI currently exposes URL of the following form to inspect the status of a running workflow:

https://localhost:8080/domain/cadence-canary/workflows/cron.workflow.sanity/d1e5c195-d8a7-488b-bd5b-d238f97459d2/summary

Would be very nice if the UI could also expose an URL with only the workflow-id which redirects to the currenlty running RunID of that workflow

https://localhost:8080/domain/cadence-canary/workflows/cron.workflow.sanity

History failed to load when an activity is canceled

I'm using cadence web 3.2.2 with cadence server 0.5.7

I execute a workflow with an activity inside, which returns ErrResultPending.

At some point, I cancel the context passed to the ExecuteActivity above.

The activity is requested canceled as a result, but then when I load the workflow in the UI, the history tab is "hanging"

Looking at the javascript console, I see this output:
TypeError: __WEBPACK_IMPORTED_MODULE_2__summarize_events__.a[e.eventType] is not a function at timeline-events.js:40 at Array.forEach (<anonymous>) at timeline-events.js:17 at VueComponent.timelineEvents (history.vue:135) at Watcher.get (vue.esm.js:3142) at Watcher.evaluate (vue.esm.js:3249) at VueComponent.computedGetter [as timelineEvents] (vue.esm.js:3507) at VueComponent.render (history.vue?20ac:1) at VueComponent.Vue._render (vue.esm.js:4544) at VueComponent.updateComponent (vue.esm.js:2788) logError @ vue.esm.js:1741

Upgrade the date range picker in workflows list with a dropdown of relative times

Rather than the user pick absolute times, defaulting to the last 24 hours, have the users pick options from within the last X Y (24 hours, 3, days, 7 days, 4 weeks probably) and remember that relative choice to refreshing the page is more predictable if done a day later or more.

Absolute times will still be supported as a "Custom..." option in this dropdown.

GetWorkflowExecutionHistory throws error

Could not parse body (arg3) argument. Expected Thrift encoded arg3 for endpoint WorkflowService::GetWorkflowExecutionHistory. Got � instead of Thrift. Parsing error was: value must be a valid member of enumeration EventType, got: 41.

The thrift file need to update

Add time component to the "Custom Range" date control

Having ability to set time when filtering would give more flexibility while using Cadence.

Just one usecase when we needed this desperately was when ~10000 workflows failed in a short time period, and we were unable to see anything happening that day before failures, because it would've required scrolling down through 10000 failed workflows in the list.

Workflow summary page does not render under some circustances

I'm seeing the following error in some of my running workflows, but I haven't figured out yet how to reproduce consistently:

index.vue:193 TypeError: _summarizeEvents.summarizeEvents[e.eventType] is not a function
    at map-timeline-events.js:53
    at Array.forEach (<anonymous>)
    at exports.default (map-timeline-events.js:22)
    at getHistoryTimelineEvents (get-history-timeline-events.js:5)
    at index.vue:175

One-line details column in history grid

For a more compact view option, having the details column be one line, highlighting the most important properties, would be effective for users scanning for interesting events.

Infinite scroll sometimes not working

When listing workflows, the infinite scroll should request the next page when the user scrolls to the bottom. This sometimes does not work but is not consistent. For instance, resizing the browser window can sometimes trigger the next page.

Export API

Currently the export functionality only dumps what the browser has currently loaded into a file. The server should have an endpoint to stream the results.

Show activity's error message during retries

Currently, when an activity fails and is being retried, there is no way (afaik) to see the error message that caused the activity to fail.

The UI only shows the number of retry attempts made in the workflow's Summary tab. Using the CLI to describe the workflow, we can only see that the LastFailureReason is cadenceInternal:Generic.

Could we surface the failed activity's error message in the UI somewhere to help introspect the state of the workflow and to help debug faulty activities?

Mutable state on workflow summary page does not show all the info

For example, LastFailureReason for activity should be useful info to include.

"mutableStateInCache": "{"ActivityInfos":{"14":{"Version":-24,"ScheduleID":14,"ScheduledEventBatchID":13,"ScheduledEvent":null,"ScheduledTime":"2020-01-08T04:59:25.636Z","StartedID":-124,"StartedEvent":null,"StartedTime":"2020-01-08T04:59:25.668Z","ActivityID":"1","RequestID":"d2eea2f9-8134-4270-9748-b9f7ae3de0ed","Details":"eyJDdXJyZW50SW5kZXgiOjM4MjU0OCwiTnVtQ2FuZGlkYXRlcyI6NDY2MTU1LCJPd25lclVVSUQiOiJlMGU5YzBlZS1kOGVmLTQyM2UtYmVmNC05Zjg3NWY5NmE5YzEifQo=","ScheduleToStartTimeout":21000,"ScheduleToCloseTimeout":28800,"StartToCloseTimeout":24000,"HeartbeatTimeout":30,"CancelRequested":false,"CancelRequestID":-23,"LastHeartBeatUpdatedTime":"2020-01-08T06:16:47.532Z","TimerTaskStatus":12,"Attempt":1,"DomainID":"f89e6f93-8840-4430-8a79-fef018c1125c","StartedIdentity":"140@agent3354-dca1@fx-worker-batch-launching","TaskList":"fx-worker-batch-launching","HasRetryPolicy":true,"InitialInterval":1,"BackoffCoefficient":2,"MaximumInterval":60,"ExpirationTime":"2020-01-08T06:19:24.563Z","MaximumAttempts":5,"NonRetriableErrors":null,"LastFailureReason":"cadenceInternal:Timeout START_TO_CLOSE","LastWorkerIdentity":"140@agent3354-dca1@fx-worker-batch-launching","LastFailureDetails":null,"LastHeartbeatTimeoutVisibility":0}},"TimerInfos":{},"ChildExecutionInfos":{},"RequestCancelInfos":{},"SignalInfos":{},"SignalRequestedIDs":{},"ExecutionInfo":{"DomainID":"f89e6f93-8840-4430-8a79-fef018c1125c","WorkflowID":"7a894e63-7030-4156-a70b-62701f0d7c2a","RunID":"75a9e64d-e37e-48a7-ae4d-5d2c0a01d2b9","ParentDomainID":"","ParentWorkflowID":"","ParentRunID":"","InitiatedID":-7,"CompletionEventBatchID":15,"CompletionEvent":null,"TaskList":"fx-worker-batch-launching","WorkflowTypeName":"BatchStatementWorkflow","WorkflowTimeout":28800,"DecisionTimeoutValue":240,"ExecutionContext":null,"State":2,"CloseStatus":6,"LastFirstEventID":1,"LastEventTaskID":445667987,"NextEventID":16,"LastProcessedEvent":12,"StartTimestamp":"2020-01-07T22:17:02.43Z","LastUpdatedTimestamp":"2020-01-08T06:17:02.443Z","CreateRequestID":"678ddc54-0a54-45b9-a83c-4728a70fb1f6","SignalCount":0,"DecisionVersion":-24,"DecisionScheduleID":-23,"DecisionStartedID":-23,"DecisionRequestID":"emptyUuid","DecisionTimeout":0,"DecisionAttempt":0,"DecisionStartedTimestamp":0,"DecisionScheduledTimestamp":0,"DecisionOriginalScheduledTimestamp":1578435564540788996,"CancelRequested":false,"CancelRequestID":"","StickyTaskList":"","StickyScheduleToStartTimeout":0,"ClientLibraryVersion":"","ClientFeatureVersion":"","ClientImpl":"","AutoResetPoints":{"points":[{"binaryChecksum":"d7b7e8ca04c8ffe21313b5dfbea85132","runId":"75a9e64d-e37e-48a7-ae4d-5d2c0a01d2b9","firstDecisionCompletedId":4,"createdTimeNano":1578435422449596398,"resettable":true}]},"Memo":null,"SearchAttributes":null,"Attempt":0,"HasRetryPolicy":false,"InitialInterval":0,"BackoffCoefficient":0,"MaximumInterval":0,"ExpirationTime":"0001-01-01T00:00:00Z","MaximumAttempts":0,"NonRetriableErrors":null,"BranchToken":"WQsACgAAACQ3NWE5ZTY0ZC1lMzdlLTQ4YTctYWU0ZC01ZDJjMGEwMWQyYjkLABQAAAAkZjRkYzhjOTAtNjEyMy00ODYzLWIxZDEtOGI3NDQyMjUxNzJjDwAeDAAAAAAA","CronSchedule":"","ExpirationSeconds":0},"ExecutionStats":null,"ReplicationState":null,"BufferedEvents":[],"VersionHistories":null}",

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.