diff --git a/feature_reflect.go b/feature_reflect.go index bcfaf6f..08dd4cb 100644 --- a/feature_reflect.go +++ b/feature_reflect.go @@ -6,6 +6,7 @@ import ( "fmt" "reflect" "unsafe" + "time" ) // Decoder is an internal type registered to cache as needed. @@ -169,11 +170,12 @@ func (encoder *optionalEncoder) isEmpty(ptr unsafe.Pointer) bool { } type placeholderEncoder struct { - valueEncoder Encoder + cfg *frozenConfig + cacheKey reflect.Type } func (encoder *placeholderEncoder) encode(ptr unsafe.Pointer, stream *Stream) { - encoder.valueEncoder.encode(ptr, stream) + encoder.getRealEncoder().encode(ptr, stream) } func (encoder *placeholderEncoder) encodeInterface(val interface{}, stream *Stream) { @@ -181,15 +183,39 @@ func (encoder *placeholderEncoder) encodeInterface(val interface{}, stream *Stre } func (encoder *placeholderEncoder) isEmpty(ptr unsafe.Pointer) bool { - return encoder.valueEncoder.isEmpty(ptr) + return encoder.getRealEncoder().isEmpty(ptr) +} + +func (encoder *placeholderEncoder) getRealEncoder() Encoder { + for i := 0; i < 30; i++ { + realDecoder := encoder.cfg.getEncoderFromCache(encoder.cacheKey) + _, isPlaceholder := realDecoder.(*placeholderEncoder) + if isPlaceholder { + time.Sleep(time.Second) + } else { + return realDecoder + } + } + panic(fmt.Sprintf("real encoder not found for cache key: %v", encoder.cacheKey)) } type placeholderDecoder struct { - valueDecoder Decoder + cfg *frozenConfig + cacheKey reflect.Type } func (decoder *placeholderDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { - decoder.valueDecoder.decode(ptr, iter) + for i := 0; i < 30; i++ { + realDecoder := decoder.cfg.getDecoderFromCache(decoder.cacheKey) + _, isPlaceholder := realDecoder.(*placeholderDecoder) + if isPlaceholder { + time.Sleep(time.Second) + } else { + realDecoder.decode(ptr, iter) + return + } + } + panic(fmt.Sprintf("real decoder not found for cache key: %v", decoder.cacheKey)) } // emptyInterface is the header for an interface{} value. @@ -283,10 +309,9 @@ func decoderOfType(cfg *frozenConfig, typ reflect.Type) (Decoder, error) { if cachedDecoder != nil { return cachedDecoder, nil } - placeholder := &placeholderDecoder{} + placeholder := &placeholderDecoder{cfg: cfg, cacheKey: cacheKey} cfg.addDecoderToCache(cacheKey, placeholder) newDecoder, err := createDecoderOfType(cfg, typ) - placeholder.valueDecoder = newDecoder cfg.addDecoderToCache(cacheKey, newDecoder) return newDecoder, err } @@ -382,10 +407,9 @@ func encoderOfType(cfg *frozenConfig, typ reflect.Type) (Encoder, error) { if cachedEncoder != nil { return cachedEncoder, nil } - placeholder := &placeholderEncoder{} + placeholder := &placeholderEncoder{cfg: cfg, cacheKey: cacheKey} cfg.addEncoderToCache(cacheKey, placeholder) newEncoder, err := createEncoderOfType(cfg, typ) - placeholder.valueEncoder = newEncoder cfg.addEncoderToCache(cacheKey, newEncoder) return newEncoder, err }