Hi Tarrence! Thank you. I have a few answers to your questions.
1. The Go Direct Runner doesn't test coders or serialization, and outright 
avoids it, so it's erroneously passing in cases like this.

2. After about version 2.30 IIRC the Go SDK stopped using JSON as the default 
coder for struct types in favour of Beam Schema Row coders. As a more compact 
binary encoding it's much more efficient than JSON, largely because the types 
are static thoughout a pipeline. However, as a result it's unable to handle 
interface types. JSON gets away with interface{} types because it encodes the 
field names for every element, among other things.

So my recommendation would be to not lean on interfaces for elements within 
pipelines.

That said, one is always free to create and register a custom coder though that 
uses JSON under the hood, especially if the elements are few, or as I'm 
guessing, are shelling out to some other process in a custom container...

eg.
```
func init() {
  beam.RegisterCoder(reflect.TypeOf(Execer{}), jsonEnc, jsonDec)
}

func jsonEnc(in beam.T) ([]byte, error) {
       v := in.(Execer)
        // ... json marshalling code ...
}

func jsonDecValue(in []byte) (beam.T, error) {
      v := Execer{}
        // ... json unmarshalling code ...
      return v, nil
}
```

Which should get you the desired behavior on distributed runners.

Cheers,
Robert Burke
Beam Go Busybody

On 2021/08/01 01:18:40, Tarrence van As <[email protected]> wrote: 
> An additional piece of information that might be of interest:
> 
> This issue occurs if I try to create a PCollection with `beam.Create(s,
> Execer{q, a})` but seems to work (at least with the direct runner) when I
> emit the struct like `emit(Execer{q, a})`.
> 
> Tarrence
> 
> On Sat, Jul 31, 2021 at 3:36 PM Tarrence van As <[email protected]>
> wrote:
> 
> > Hi,
> >
> > Thank you for the great work on Beam. I'm using the golang sdk and hoping
> > someone might be able to help with defining a customer coder for a type.
> >
> > I have a type like this:
> > type Execer struct {
> > Query string `json:"query,omitempty"`
> > Args []interface{} `json:"args,omitempty"`
> > }
> >
> > Where each element in Args implements `driver.Valuer`.
> >
> > When trying to run with this as an element of a PCollection I get:
> >
> > panic: unable to encode type: interface {}
> >
> > My guess is that I need to define an encode/decode method for the type,
> > but I'm not sure what interface it should implement. Any direction would be
> > appreciated.
> >
> > Tarrence
> >
> >
> 

Reply via email to