Updated logic to handle a single core

The remote loader was blocking the only thread.

Signed-off-by: quobix <dave@quobix.com>
This commit is contained in:
quobix
2023-10-24 17:54:02 -04:00
parent f644fbb250
commit e26897d8a1
3 changed files with 18 additions and 12 deletions

View File

@@ -119,9 +119,10 @@ func ExampleNewDocument_fromWithDocumentConfigurationSuccess() {
// create a DocumentConfiguration that allows loading file and remote references, and sets the baseURL // create a DocumentConfiguration that allows loading file and remote references, and sets the baseURL
// to somewhere that can resolve the relative references. // to somewhere that can resolve the relative references.
config := datamodel.DocumentConfiguration{ config := datamodel.DocumentConfiguration{
AllowFileReferences: true,
AllowRemoteReferences: true,
BaseURL: baseURL, BaseURL: baseURL,
Logger: slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
Level: slog.LevelError,
})),
} }
// create a new document from specification bytes // create a new document from specification bytes

View File

@@ -8,6 +8,7 @@ import (
"fmt" "fmt"
"github.com/pb33f/libopenapi/datamodel" "github.com/pb33f/libopenapi/datamodel"
"log/slog" "log/slog"
"runtime"
"golang.org/x/sync/syncmap" "golang.org/x/sync/syncmap"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
@@ -259,6 +260,9 @@ func (i *RemoteFS) Open(remoteURL string) (fs.File, error) {
// if we're processing, we need to block and wait for the file to be processed // if we're processing, we need to block and wait for the file to be processed
// try path first // try path first
if _, ok := i.ProcessingFiles.Load(remoteParsedURL.Path); ok { if _, ok := i.ProcessingFiles.Load(remoteParsedURL.Path); ok {
// we can't block if we only have a single CPU, as we'll deadlock, only when we're running in parallel
// can we block threads.
if runtime.GOMAXPROCS(-1) > 1 {
i.logger.Debug("waiting for existing fetch to complete", "file", remoteURL, "remoteURL", remoteParsedURL.String()) i.logger.Debug("waiting for existing fetch to complete", "file", remoteURL, "remoteURL", remoteParsedURL.String())
for { for {
if wf, ko := i.Files.Load(remoteParsedURL.Path); ko { if wf, ko := i.Files.Load(remoteParsedURL.Path); ko {
@@ -266,6 +270,7 @@ func (i *RemoteFS) Open(remoteURL string) (fs.File, error) {
} }
} }
} }
}
// add to processing // add to processing
i.ProcessingFiles.Store(remoteParsedURL.Path, true) i.ProcessingFiles.Store(remoteParsedURL.Path, true)
@@ -288,10 +293,10 @@ func (i *RemoteFS) Open(remoteURL string) (fs.File, error) {
i.logger.Debug("loading remote file", "file", remoteURL, "remoteURL", remoteParsedURL.String()) i.logger.Debug("loading remote file", "file", remoteURL, "remoteURL", remoteParsedURL.String())
// no handler func? use the default client. //// no handler func? use the default client.
if i.RemoteHandlerFunc == nil { //if i.RemoteHandlerFunc == nil {
i.RemoteHandlerFunc = i.defaultClient.Get // i.RemoteHandlerFunc = i.defaultClient.Get
} //}
response, clientErr := i.RemoteHandlerFunc(remoteParsedURL.String()) response, clientErr := i.RemoteHandlerFunc(remoteParsedURL.String())
if clientErr != nil { if clientErr != nil {

View File

@@ -103,7 +103,7 @@ func TestSpecIndex_DigitalOcean(t *testing.T) {
cf.AllowRemoteLookup = true cf.AllowRemoteLookup = true
cf.AvoidCircularReferenceCheck = true cf.AvoidCircularReferenceCheck = true
cf.Logger = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ cf.Logger = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
Level: slog.LevelError, Level: slog.LevelDebug,
})) }))
// setting this baseURL will override the base // setting this baseURL will override the base