releaseOpenRefs releases every project and file ref this session is holding open in the project session. This keeps the API's ref counts balanced when an API session is shut down while sharing a longer-lived project session (e.g. one backing an LSP server), so API-opened projects and files aren't le
()
| 2869 | // backing an LSP server), so API-opened projects and files aren't leaked. Only |
| 2870 | // refs the session currently holds are closed, so it never over-releases. |
| 2871 | func (s *Session) releaseOpenRefs() { |
| 2872 | s.updateMu.Lock() |
| 2873 | defer s.updateMu.Unlock() |
| 2874 | |
| 2875 | if s.openProjects.Len() == 0 && s.openFiles.Len() == 0 { |
| 2876 | return |
| 2877 | } |
| 2878 | |
| 2879 | apiRequest := &project.APISnapshotRequest{} |
| 2880 | if s.openProjects.Len() > 0 { |
| 2881 | apiRequest.CloseProjects = s.openProjects.Clone() |
| 2882 | } |
| 2883 | if s.openFiles.Len() > 0 { |
| 2884 | apiRequest.CloseFiles = s.openFiles.Clone() |
| 2885 | } |
| 2886 | snapshot, err := s.projectSession.APIUpdate(context.Background(), project.FileChangeSummary{}, apiRequest) |
| 2887 | // APIUpdate returns a ref'd snapshot even on error; always release it. |
| 2888 | snapshot.Deref(s.projectSession) |
| 2889 | if err != nil { |
| 2890 | return |
| 2891 | } |
| 2892 | |
| 2893 | s.openProjects.Clear() |
| 2894 | s.openFiles.Clear() |
| 2895 | } |
| 2896 | |
| 2897 | func formatSessionID(id uint64) string { |
| 2898 | return fmt.Sprintf("api-session-%d", id) |