@@ -100,25 +100,23 @@ func (m *marshallersCache) loadMarshaller(rType reflect.Type, config *config.IOC
100100 return marshaller , nil
101101}
102102
103- func (c * pathCache ) loadOrGetMarshaller (rType reflect.Type , config * config.IOConfig , path string , outputPath string , tag * format.Tag , options ... interface {}) (marshaler , error ) {
104- value , ok := c .cache .Load (rType )
103+ func (c * pathCache ) loadOrGetMarshaller (rType reflect.Type , cfg * config.IOConfig , path , outPath string , tag * format.Tag , options ... interface {}) (marshaler , error ) {
104+
105+ placeholder := newDeferred ()
106+ value , ok := c .cache .LoadOrStore (rType , placeholder )
105107 if ok {
106108 return value .(marshaler ), nil
107109 }
108110
109- // Place a deferred placeholder to break recursive graphs for this path and type.
110- placeholder := & deferredMarshaller {}
111- c .storeMarshaler (rType , placeholder )
112-
113- aMarshaler , err := c .getMarshaller (rType , config , path , outputPath , tag , options ... )
111+ aMarshaller , err := c .getMarshaller (rType , cfg , path , outPath , tag , options ... )
114112 if err != nil {
113+ placeholder .fail (err ) // unblock anyone holding the promise
114+ c .cache .CompareAndDelete (rType , placeholder ) // allow a clean retry later
115115 return nil , err
116116 }
117117
118- // Swap placeholder with the real marshaller and set target for any users that captured it.
119- placeholder .setTarget (aMarshaler )
120- c .storeMarshaler (rType , aMarshaler )
121- return aMarshaler , nil
118+ placeholder .setTarget (aMarshaller ) // resolve success
119+ return aMarshaller , nil
122120}
123121
124122func (c * pathCache ) getMarshaller (rType reflect.Type , config * config.IOConfig , path string , outputPath string , tag * format.Tag , options ... interface {}) (marshaler , error ) {
0 commit comments