(sessID, clientID string)
| 759 | } |
| 760 | |
| 761 | func (srv *Server) clientFromIDs(sessID, clientID string) (*daggerClient, error) { |
| 762 | if sessID == "" { |
| 763 | return nil, fmt.Errorf("missing session ID") |
| 764 | } |
| 765 | if clientID == "" { |
| 766 | return nil, fmt.Errorf("missing client ID") |
| 767 | } |
| 768 | srv.daggerSessionsMu.RLock() |
| 769 | sess, ok := srv.daggerSessions[sessID] |
| 770 | srv.daggerSessionsMu.RUnlock() |
| 771 | if !ok { |
| 772 | // This error can happen due to per-LLB-vertex deduplication in the buildkit solver, |
| 773 | // where for instance the first client cancels and closes its session while others |
| 774 | // are waiting on the result. In this case its safe to retry the operation again with |
| 775 | // the still connected client metadata. |
| 776 | err := flightcontrol.RetryableError{Err: fmt.Errorf("session %q not found", sessID)} |
| 777 | return nil, err |
| 778 | } |
| 779 | |
| 780 | // The session pointer is published before initializeDaggerSession populates |
| 781 | // its fields, so gate on state under stateMu before reading them. stateMu is |
| 782 | // taken only after releasing daggerSessionsMu to avoid inverting |
| 783 | // removeDaggerSession's stateMu->daggerSessionsMu lock order. |
| 784 | sess.stateMu.RLock() |
| 785 | defer sess.stateMu.RUnlock() |
| 786 | switch sess.state { |
| 787 | case sessionStateInitialized: |
| 788 | // continue |
| 789 | case sessionStateRemoved: |
| 790 | err := flightcontrol.RetryableError{Err: fmt.Errorf("session %q not found", sessID)} |
| 791 | return nil, err |
| 792 | case sessionStateUninitialized: |
| 793 | return nil, fmt.Errorf("session %q not initialized", sessID) |
| 794 | default: |
| 795 | return nil, fmt.Errorf("session %q has unknown state %q", sessID, sess.state) |
| 796 | } |
| 797 | |
| 798 | sess.clientMu.RLock() |
| 799 | defer sess.clientMu.RUnlock() |
| 800 | client, ok := sess.clients[clientID] |
| 801 | if !ok { |
| 802 | return nil, fmt.Errorf("client %q not found", clientID) |
| 803 | } |
| 804 | |
| 805 | return client, nil |
| 806 | } |
| 807 | |
| 808 | // initialize session+client if needed, return: |
| 809 | // * the initialized client |
no outgoing calls