gogen-avro icon indicating copy to clipboard operation
gogen-avro copied to clipboard

Code refactoring

Open dmlambea opened this issue 4 years ago • 2 comments

Hi, @actgardner! Just wanted to tell you I'm doing some experiments in the branch "wip-code-refactoring" of my fork, based in the PR #127 I opened some days ago.

In my branch I tried to reduce duplicated code by applying an initial refactoring of the base types, which led to removal of the resolver package and some other minor changes in the templates. I am currently testing that branch and I've found the code a bit easier to maintain, as well as the generated Go code easier to deal with (because of #127 is handling optional unions properly). See this example:

AVRO type:

{
    "name": "OptionalUnionTestRecord",
    "type": "record",
    "fields": [
        {
            "name": "nonOption",
            "type": {
                "name": "UserRecord",
                "type": "record",
                "fields": [
                    {
                        "name": "username",
                        "type": "string"
                    },
                    {
                        "name": "userID",
                        "type": "long"
                    }
                ]
            }
        },
        {
            "name": "option",
            "type": [
                "null",
                "string",
                "int"
            ]
        }
    ]
}

Generated code snippets:

// Snippet from optional_union_test_record.go
...
type OptionalUnionTestRecord struct { 
  NonOption UserRecord           // Notice the non-pointer type
  Option    *UnionNullStringInt
}
...
// Snippet from union_null_string_int.go
...
type UnionNullStringIntTypeEnum int

const (
  UnionNullStringIntTypeEnumString UnionNullStringIntTypeEnum = 1
  UnionNullStringIntTypeEnumInt UnionNullStringIntTypeEnum = 2
)

type UnionNullStringInt struct { 
  String    string
  Int       int32
  UnionType UnionNullStringIntTypeEnum
}
...

Using these types work as one might expect:

...
// Please notice the nil Option field
rec := avro.OptionalUnionTestRecord{
  NonOption: avro.UserRecord{
    Username: "user",
    UserID:   42,
  },
}
rec.Serialize(w)  // Serializes the record using the NULL union type for Option field

The non-null types work as usual:

rec := avro.OptionalUnionTestRecord{
  ...
  Option: &avro.UnionNullStringInt{
    UnionType: avro.UnionNullStringIntTypeEnumInt,
    Int: 123,
  },
}
rec.Serialize(w)  // Serializes the record using the INT union type for Option field

While the refactored code works for me, I understand it might be a bit too much for a PR. But if you like the way my experiment is going, I would be happy to open a PR.

dmlambea avatar Mar 04 '20 10:03 dmlambea

Hey @dmlambea, sorry for the slow response. Your current PR and this proposed one both sound great. One thing I'd ask in a big refactor is if you can split the changes into individual PRs and/or commits that have a specfic purpose. That way it would be easier for me to read and give feedback on specific changes while understanding the intent behind them, versus getting one large PR and having to infer what's happening. Thanks for all your work on this!

actgardner avatar Mar 18 '20 20:03 actgardner

Hi, @actgardner, I'm sorry for not contacting you before. This COVID-19 thing is putting a lot of pressure in the gov's IT dept., and I had been focused in other priority tasks for the past days. Due to this, the works in my WIP branch has suffered a slowdown.

I am glad that you liked my proposal, thank you very much, really! Sure, I can work with you to deliver the changes in the way you find it easier. But I still have pending changes I believe you will want to include in the major version.

The most relevant part is the one relative to the proposal described in then long-forgotten #40, which I wanted to try and implement, given the fact that the optional unions are just one step behind achieving the proposal's goal. I think I've got something, but the amount of changes for adapting and testing are requiring me a lot of time, and I think it will take a little bit more of time to be PR-ready. I use gogen-avro a lot and I'd like to commit well written, tested code.

If you can wait for the final changes to be ready, I'm sure you will find it well worth it!

dmlambea avatar Mar 19 '20 19:03 dmlambea