MCPcopy Index your code
hub / github.com/cli/cli / PollPostCreateStates

Function PollPostCreateStates

internal/codespaces/states.go:40–108  ·  view source on GitHub ↗

PollPostCreateStates watches for state changes in a codespace, and calls the supplied poller for each batch of state changes. It runs until it encounters an error, including cancellation of the context.

(ctx context.Context, progress progressIndicator, apiClient apiClient, codespace *api.Codespace, poller func([]PostCreateState))

Source from the content-addressed store, hash-verified

38// and calls the supplied poller for each batch of state changes.
39// It runs until it encounters an error, including cancellation of the context.
40func PollPostCreateStates(ctx context.Context, progress progressIndicator, apiClient apiClient, codespace *api.Codespace, poller func([]PostCreateState)) (err error) {
41 codespaceConnection, err := GetCodespaceConnection(ctx, progress, apiClient, codespace)
42 if err != nil {
43 return fmt.Errorf("error connecting to codespace: %w", err)
44 }
45
46 fwd, err := portforwarder.NewPortForwarder(ctx, codespaceConnection)
47 if err != nil {
48 return fmt.Errorf("failed to create port forwarder: %w", err)
49 }
50 defer safeClose(fwd, &err)
51
52 // Ensure local port is listening before client (getPostCreateOutput) connects.
53 listen, localPort, err := ListenTCP(0, false)
54 if err != nil {
55 return err
56 }
57
58 progress.StartProgressIndicatorWithLabel("Fetching SSH Details")
59 invoker, err := rpc.CreateInvoker(ctx, fwd)
60 if err != nil {
61 return err
62 }
63 defer safeClose(invoker, &err)
64
65 remoteSSHServerPort, sshUser, err := invoker.StartSSHServer(ctx)
66 if err != nil {
67 return fmt.Errorf("error getting ssh server details: %w", err)
68 }
69 progress.StopProgressIndicator()
70
71 progress.StartProgressIndicatorWithLabel("Fetching status")
72 tunnelClosed := make(chan error, 1) // buffered to avoid sender stuckness
73 go func() {
74 opts := portforwarder.ForwardPortOpts{
75 Port: remoteSSHServerPort,
76 Internal: true,
77 }
78 tunnelClosed <- fwd.ForwardPortToListener(ctx, opts, listen)
79 }()
80
81 t := time.NewTicker(1 * time.Second)
82 defer t.Stop()
83
84 for ticks := 0; ; ticks++ {
85 select {
86 case <-ctx.Done():
87 return ctx.Err()
88
89 case err := <-tunnelClosed:
90 return fmt.Errorf("connection failed: %w", err)
91
92 case <-t.C:
93 states, err := getPostCreateOutput(ctx, localPort, sshUser)
94 // There is an active progress indicator before the first tick
95 // to show that we are fetching statuses.
96 // Once the first tick happens, we stop the indicator and let
97 // the subsequent post create states manage their own progress.

Callers 1

showStatusMethod · 0.92

Calls 13

ForwardPortToListenerMethod · 0.95
NewPortForwarderFunction · 0.92
CreateInvokerFunction · 0.92
GetCodespaceConnectionFunction · 0.85
ListenTCPFunction · 0.85
getPostCreateOutputFunction · 0.85
ErrMethod · 0.80
safeCloseFunction · 0.70
ErrorfMethod · 0.65
StartSSHServerMethod · 0.65
StopProgressIndicatorMethod · 0.65

Tested by

no test coverage detected