[jira] [Commented] (THRIFT-3752) nil collections are serialized as empty collections

2017-02-22 Thread Jens Geyer (JIRA)

[ 
https://issues.apache.org/jira/browse/THRIFT-3752?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15879232#comment-15879232
 ] 

Jens Geyer commented on THRIFT-3752:


I remember having a somewhat lengthy discussion about that during one of the 
last big rewrites of the Thrift Go bindings with the author(s) of that patch. 
Not quite sure what the main reason was, but at the end we decided to implement 
it this way. That being said, I would be happy if we come up with a better 
solution that is more aligned to the usually expected behaviour, there's 
absolutely no question about that. This is Go - so it should be possible, 
shouldn't it ;-)?

> nil collections are serialized as empty collections
> ---
>
> Key: THRIFT-3752
> URL: https://issues.apache.org/jira/browse/THRIFT-3752
> Project: Thrift
>  Issue Type: Bug
>  Components: Go - Compiler
>Reporter: John Sirois
>Assignee: John Sirois
>
> See discussion here: https://reviews.apache.org/r/45193/
> This is likely related to THRIFT-3700.
> In short, for this struct:
> {noformat}
> struct TaskQuery {
> 4: optional set taskIds
> }
> {noformat}
> The following go struct is generated:
> {noformat}
> type TaskQuery struct {
>   TaskIds  map[string]bool `thrift:"taskIds,4" json:"taskIds"`
> }
> {noformat}
> This is all well and good, since {{TaskQuery{}.TaskIds == nil}}; ie the 
> {{TaskIds}} collection field is - by default - unset.
> The problem is in the serialization for the field, which wipes out the unset 
> ({{nil}}) vs empty collection distinction at the wire level:
> {noformat}
> func (p *TaskQuery) writeField4(oprot thrift.TProtocol) (err error) {
>   if err := oprot.WriteFieldBegin("taskIds", thrift.SET, 4); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field begin 
> error 4:taskIds: ", p), err)
>   }
>   if err := oprot.WriteSetBegin(thrift.STRING, len(p.TaskIds)); err != 
> nil {
>   return thrift.PrependError("error writing set begin: ", err)
>   }
>   for v, _ := range p.TaskIds {
>   if err := oprot.WriteString(string(v)); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T. (0) field 
> write error: ", p), err)
>   }
>   }
>   if err := oprot.WriteSetEnd(); err != nil {
>   return thrift.PrependError("error writing set end: ", err)
>   }
>   if err := oprot.WriteFieldEnd(); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field end 
> error 4:taskIds: ", p), err)
>   }
>   return err
> }
> {noformat}
> So on the receiving end of the wire, a {{nil}} collection is turned into an 
> empty collection and so unset-ness cannot be distinguished from set but empty.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)


[jira] [Commented] (THRIFT-3752) nil collections are serialized as empty collections

2017-02-21 Thread John Sirois (JIRA)

[ 
https://issues.apache.org/jira/browse/THRIFT-3752?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15877173#comment-15877173
 ] 

John Sirois commented on THRIFT-3752:
-

[~jking], I don't think so. The compiler still does the {{IsSetXXX, 
WriteFieldBegin}} sequence, and the problem noted in this issue is this encodes 
a different notion of "unset requiredness" than the java compiler. The issue 
was specifically cross-lang incompatibility. So unless the java compiler has 
been changed to have the same notion of "unset requiredness" in the intervening 
time (aka if the cross-tests are enabled, complete and including all 
languages), this is probably still an issue.

> nil collections are serialized as empty collections
> ---
>
> Key: THRIFT-3752
> URL: https://issues.apache.org/jira/browse/THRIFT-3752
> Project: Thrift
>  Issue Type: Bug
>  Components: Go - Compiler
>Reporter: John Sirois
>Assignee: John Sirois
>
> See discussion here: https://reviews.apache.org/r/45193/
> This is likely related to THRIFT-3700.
> In short, for this struct:
> {noformat}
> struct TaskQuery {
> 4: optional set taskIds
> }
> {noformat}
> The following go struct is generated:
> {noformat}
> type TaskQuery struct {
>   TaskIds  map[string]bool `thrift:"taskIds,4" json:"taskIds"`
> }
> {noformat}
> This is all well and good, since {{TaskQuery{}.TaskIds == nil}}; ie the 
> {{TaskIds}} collection field is - by default - unset.
> The problem is in the serialization for the field, which wipes out the unset 
> ({{nil}}) vs empty collection distinction at the wire level:
> {noformat}
> func (p *TaskQuery) writeField4(oprot thrift.TProtocol) (err error) {
>   if err := oprot.WriteFieldBegin("taskIds", thrift.SET, 4); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field begin 
> error 4:taskIds: ", p), err)
>   }
>   if err := oprot.WriteSetBegin(thrift.STRING, len(p.TaskIds)); err != 
> nil {
>   return thrift.PrependError("error writing set begin: ", err)
>   }
>   for v, _ := range p.TaskIds {
>   if err := oprot.WriteString(string(v)); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T. (0) field 
> write error: ", p), err)
>   }
>   }
>   if err := oprot.WriteSetEnd(); err != nil {
>   return thrift.PrependError("error writing set end: ", err)
>   }
>   if err := oprot.WriteFieldEnd(); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field end 
> error 4:taskIds: ", p), err)
>   }
>   return err
> }
> {noformat}
> So on the receiving end of the wire, a {{nil}} collection is turned into an 
> empty collection and so unset-ness cannot be distinguished from set but empty.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)


[jira] [Commented] (THRIFT-3752) nil collections are serialized as empty collections

2017-02-21 Thread James E. King, III (JIRA)

[ 
https://issues.apache.org/jira/browse/THRIFT-3752?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15877116#comment-15877116
 ] 

James E. King, III commented on THRIFT-3752:


Is it possible THRIFT-4011 helped to resolve this issue?

> nil collections are serialized as empty collections
> ---
>
> Key: THRIFT-3752
> URL: https://issues.apache.org/jira/browse/THRIFT-3752
> Project: Thrift
>  Issue Type: Bug
>  Components: Go - Compiler
>Reporter: John Sirois
>Assignee: John Sirois
>
> See discussion here: https://reviews.apache.org/r/45193/
> This is likely related to THRIFT-3700.
> In short, for this struct:
> {noformat}
> struct TaskQuery {
> 4: optional set taskIds
> }
> {noformat}
> The following go struct is generated:
> {noformat}
> type TaskQuery struct {
>   TaskIds  map[string]bool `thrift:"taskIds,4" json:"taskIds"`
> }
> {noformat}
> This is all well and good, since {{TaskQuery{}.TaskIds == nil}}; ie the 
> {{TaskIds}} collection field is - by default - unset.
> The problem is in the serialization for the field, which wipes out the unset 
> ({{nil}}) vs empty collection distinction at the wire level:
> {noformat}
> func (p *TaskQuery) writeField4(oprot thrift.TProtocol) (err error) {
>   if err := oprot.WriteFieldBegin("taskIds", thrift.SET, 4); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field begin 
> error 4:taskIds: ", p), err)
>   }
>   if err := oprot.WriteSetBegin(thrift.STRING, len(p.TaskIds)); err != 
> nil {
>   return thrift.PrependError("error writing set begin: ", err)
>   }
>   for v, _ := range p.TaskIds {
>   if err := oprot.WriteString(string(v)); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T. (0) field 
> write error: ", p), err)
>   }
>   }
>   if err := oprot.WriteSetEnd(); err != nil {
>   return thrift.PrependError("error writing set end: ", err)
>   }
>   if err := oprot.WriteFieldEnd(); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field end 
> error 4:taskIds: ", p), err)
>   }
>   return err
> }
> {noformat}
> So on the receiving end of the wire, a {{nil}} collection is turned into an 
> empty collection and so unset-ness cannot be distinguished from set but empty.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)


[jira] [Commented] (THRIFT-3752) nil collections are serialized as empty collections

2016-06-10 Thread Connor Gorman (JIRA)

[ 
https://issues.apache.org/jira/browse/THRIFT-3752?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15324969#comment-15324969
 ] 

Connor Gorman commented on THRIFT-3752:
---

Hey [~jsirois],

How is this going? I can jump in and help if you'd like. Considering this is 
for Aurora, watch out for https://issues.apache.org/jira/browse/THRIFT-3851. 
Making a patch for it now

> nil collections are serialized as empty collections
> ---
>
> Key: THRIFT-3752
> URL: https://issues.apache.org/jira/browse/THRIFT-3752
> Project: Thrift
>  Issue Type: Bug
>  Components: Go - Compiler
>Reporter: John Sirois
>Assignee: John Sirois
>
> See discussion here: https://reviews.apache.org/r/45193/
> This is likely related to THRIFT-3700.
> In short, for this struct:
> {noformat}
> struct TaskQuery {
> 4: optional set taskIds
> }
> {noformat}
> The following go struct is generated:
> {noformat}
> type TaskQuery struct {
>   TaskIds  map[string]bool `thrift:"taskIds,4" json:"taskIds"`
> }
> {noformat}
> This is all well and good, since {{TaskQuery{}.TaskIds == nil}}; ie the 
> {{TaskIds}} collection field is - by default - unset.
> The problem is in the serialization for the field, which wipes out the unset 
> ({{nil}}) vs empty collection distinction at the wire level:
> {noformat}
> func (p *TaskQuery) writeField4(oprot thrift.TProtocol) (err error) {
>   if err := oprot.WriteFieldBegin("taskIds", thrift.SET, 4); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field begin 
> error 4:taskIds: ", p), err)
>   }
>   if err := oprot.WriteSetBegin(thrift.STRING, len(p.TaskIds)); err != 
> nil {
>   return thrift.PrependError("error writing set begin: ", err)
>   }
>   for v, _ := range p.TaskIds {
>   if err := oprot.WriteString(string(v)); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T. (0) field 
> write error: ", p), err)
>   }
>   }
>   if err := oprot.WriteSetEnd(); err != nil {
>   return thrift.PrependError("error writing set end: ", err)
>   }
>   if err := oprot.WriteFieldEnd(); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field end 
> error 4:taskIds: ", p), err)
>   }
>   return err
> }
> {noformat}
> So on the receiving end of the wire, a {{nil}} collection is turned into an 
> empty collection and so unset-ness cannot be distinguished from set but empty.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


[jira] [Commented] (THRIFT-3752) nil collections are serialized as empty collections

2016-03-30 Thread Jens Geyer (JIRA)

[ 
https://issues.apache.org/jira/browse/THRIFT-3752?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15218753#comment-15218753
 ] 

Jens Geyer commented on THRIFT-3752:


Correct, thanks. The same behaviour is used by some other languages as well. 
I'll add that information to the docs.

> nil collections are serialized as empty collections
> ---
>
> Key: THRIFT-3752
> URL: https://issues.apache.org/jira/browse/THRIFT-3752
> Project: Thrift
>  Issue Type: Bug
>  Components: Go - Compiler
>Reporter: John Sirois
>Assignee: John Sirois
>
> See discussion here: https://reviews.apache.org/r/45193/
> This is likely related to THRIFT-3700.
> In short, for this struct:
> {noformat}
> struct TaskQuery {
> 4: optional set taskIds
> }
> {noformat}
> The following go struct is generated:
> {noformat}
> type TaskQuery struct {
>   TaskIds  map[string]bool `thrift:"taskIds,4" json:"taskIds"`
> }
> {noformat}
> This is all well and good, since {{TaskQuery{}.TaskIds == nil}}; ie the 
> {{TaskIds}} collection field is - by default - unset.
> The problem is in the serialization for the field, which wipes out the unset 
> ({{nil}}) vs empty collection distinction at the wire level:
> {noformat}
> func (p *TaskQuery) writeField4(oprot thrift.TProtocol) (err error) {
>   if err := oprot.WriteFieldBegin("taskIds", thrift.SET, 4); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field begin 
> error 4:taskIds: ", p), err)
>   }
>   if err := oprot.WriteSetBegin(thrift.STRING, len(p.TaskIds)); err != 
> nil {
>   return thrift.PrependError("error writing set begin: ", err)
>   }
>   for v, _ := range p.TaskIds {
>   if err := oprot.WriteString(string(v)); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T. (0) field 
> write error: ", p), err)
>   }
>   }
>   if err := oprot.WriteSetEnd(); err != nil {
>   return thrift.PrependError("error writing set end: ", err)
>   }
>   if err := oprot.WriteFieldEnd(); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field end 
> error 4:taskIds: ", p), err)
>   }
>   return err
> }
> {noformat}
> So on the receiving end of the wire, a {{nil}} collection is turned into an 
> empty collection and so unset-ness cannot be distinguished from set but empty.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


[jira] [Commented] (THRIFT-3752) nil collections are serialized as empty collections

2016-03-27 Thread John Sirois (JIRA)

[ 
https://issues.apache.org/jira/browse/THRIFT-3752?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15213669#comment-15213669
 ] 

John Sirois commented on THRIFT-3752:
-

Actually [~jensg] - I can't make sense of the spec you added for this case.  If 
I look at the java generated serialization code for a no-requiredness set 
I find:
{noformat}
  if (struct.instanceIds != null) {
oprot.writeFieldBegin(INSTANCE_IDS_FIELD_DESC);
{
  oprot.writeSetBegin(new 
org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.I32, 
struct.instanceIds.size()));
  for (int _iter143 : struct.instanceIds)
  {
oprot.writeI32(_iter143);
  }
  oprot.writeSetEnd();
}
oprot.writeFieldEnd();
  }
{noformat}

Your spec in THRIFT-3756 says "Write: Like required, the fields are always 
written.".  In the java case though, the field is only written when non-null - 
which is a good thing, since it allows the read-side of the wire to correctly 
interpret this field as unset.

> nil collections are serialized as empty collections
> ---
>
> Key: THRIFT-3752
> URL: https://issues.apache.org/jira/browse/THRIFT-3752
> Project: Thrift
>  Issue Type: Bug
>  Components: Go - Compiler
>Reporter: John Sirois
>Assignee: John Sirois
>
> See discussion here: https://reviews.apache.org/r/45193/
> This is likely related to THRIFT-3700.
> In short, for this struct:
> {noformat}
> struct TaskQuery {
> 4: optional set taskIds
> }
> {noformat}
> The following go struct is generated:
> {noformat}
> type TaskQuery struct {
>   TaskIds  map[string]bool `thrift:"taskIds,4" json:"taskIds"`
> }
> {noformat}
> This is all well and good, since {{TaskQuery{}.TaskIds == nil}}; ie the 
> {{TaskIds}} collection field is - by default - unset.
> The problem is in the serialization for the field, which wipes out the unset 
> ({{nil}}) vs empty collection distinction at the wire level:
> {noformat}
> func (p *TaskQuery) writeField4(oprot thrift.TProtocol) (err error) {
>   if err := oprot.WriteFieldBegin("taskIds", thrift.SET, 4); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field begin 
> error 4:taskIds: ", p), err)
>   }
>   if err := oprot.WriteSetBegin(thrift.STRING, len(p.TaskIds)); err != 
> nil {
>   return thrift.PrependError("error writing set begin: ", err)
>   }
>   for v, _ := range p.TaskIds {
>   if err := oprot.WriteString(string(v)); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T. (0) field 
> write error: ", p), err)
>   }
>   }
>   if err := oprot.WriteSetEnd(); err != nil {
>   return thrift.PrependError("error writing set end: ", err)
>   }
>   if err := oprot.WriteFieldEnd(); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field end 
> error 4:taskIds: ", p), err)
>   }
>   return err
> }
> {noformat}
> So on the receiving end of the wire, a {{nil}} collection is turned into an 
> empty collection and so unset-ness cannot be distinguished from set but empty.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


[jira] [Commented] (THRIFT-3752) nil collections are serialized as empty collections

2016-03-27 Thread John Sirois (JIRA)

[ 
https://issues.apache.org/jira/browse/THRIFT-3752?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15213646#comment-15213646
 ] 

John Sirois commented on THRIFT-3752:
-

Noting the not-quite-yet-minted docs are here: 
https://github.com/Jens-G/thrift/blob/THRIFT-3756/doc/specs/idl.md
I'll proceed with a fix that conforms to those docs.

> nil collections are serialized as empty collections
> ---
>
> Key: THRIFT-3752
> URL: https://issues.apache.org/jira/browse/THRIFT-3752
> Project: Thrift
>  Issue Type: Bug
>  Components: Go - Compiler
>Reporter: John Sirois
>Assignee: John Sirois
>
> See discussion here: https://reviews.apache.org/r/45193/
> This is likely related to THRIFT-3700.
> In short, for this struct:
> {noformat}
> struct TaskQuery {
> 4: optional set taskIds
> }
> {noformat}
> The following go struct is generated:
> {noformat}
> type TaskQuery struct {
>   TaskIds  map[string]bool `thrift:"taskIds,4" json:"taskIds"`
> }
> {noformat}
> This is all well and good, since {{TaskQuery{}.TaskIds == nil}}; ie the 
> {{TaskIds}} collection field is - by default - unset.
> The problem is in the serialization for the field, which wipes out the unset 
> ({{nil}}) vs empty collection distinction at the wire level:
> {noformat}
> func (p *TaskQuery) writeField4(oprot thrift.TProtocol) (err error) {
>   if err := oprot.WriteFieldBegin("taskIds", thrift.SET, 4); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field begin 
> error 4:taskIds: ", p), err)
>   }
>   if err := oprot.WriteSetBegin(thrift.STRING, len(p.TaskIds)); err != 
> nil {
>   return thrift.PrependError("error writing set begin: ", err)
>   }
>   for v, _ := range p.TaskIds {
>   if err := oprot.WriteString(string(v)); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T. (0) field 
> write error: ", p), err)
>   }
>   }
>   if err := oprot.WriteSetEnd(); err != nil {
>   return thrift.PrependError("error writing set end: ", err)
>   }
>   if err := oprot.WriteFieldEnd(); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field end 
> error 4:taskIds: ", p), err)
>   }
>   return err
> }
> {noformat}
> So on the receiving end of the wire, a {{nil}} collection is turned into an 
> empty collection and so unset-ness cannot be distinguished from set but empty.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


[jira] [Commented] (THRIFT-3752) nil collections are serialized as empty collections

2016-03-23 Thread John Sirois (JIRA)

[ 
https://issues.apache.org/jira/browse/THRIFT-3752?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15209376#comment-15209376
 ] 

John Sirois commented on THRIFT-3752:
-

OK - great.  Thanks [~jensg].  After hitting this incompat in Go clients of the 
java Aurora scheduler, my 1st searches after not finding thrift docs [1][2] 
landed me here which made me suspect the non-comformance of thrift compiler 
backend verticals was more widespread.  I'll pretend its limited to only the Go 
backend until I have evidence otherwise!

[1] https://twitter.github.io/scrooge/Semantics.html
[2] http://lionet.livejournal.com/66899.html

> nil collections are serialized as empty collections
> ---
>
> Key: THRIFT-3752
> URL: https://issues.apache.org/jira/browse/THRIFT-3752
> Project: Thrift
>  Issue Type: Bug
>  Components: Go - Compiler
>Reporter: John Sirois
>Assignee: John Sirois
>
> See discussion here: https://reviews.apache.org/r/45193/
> This is likely related to THRIFT-3700.
> In short, for this struct:
> {noformat}
> struct TaskQuery {
> 4: optional set taskIds
> }
> {noformat}
> The following go struct is generated:
> {noformat}
> type TaskQuery struct {
>   TaskIds  map[string]bool `thrift:"taskIds,4" json:"taskIds"`
> }
> {noformat}
> This is all well and good, since {{TaskQuery{}.TaskIds == nil}}; ie the 
> {{TaskIds}} collection field is - by default - unset.
> The problem is in the serialization for the field, which wipes out the unset 
> ({{nil}}) vs empty collection distinction at the wire level:
> {noformat}
> func (p *TaskQuery) writeField4(oprot thrift.TProtocol) (err error) {
>   if err := oprot.WriteFieldBegin("taskIds", thrift.SET, 4); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field begin 
> error 4:taskIds: ", p), err)
>   }
>   if err := oprot.WriteSetBegin(thrift.STRING, len(p.TaskIds)); err != 
> nil {
>   return thrift.PrependError("error writing set begin: ", err)
>   }
>   for v, _ := range p.TaskIds {
>   if err := oprot.WriteString(string(v)); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T. (0) field 
> write error: ", p), err)
>   }
>   }
>   if err := oprot.WriteSetEnd(); err != nil {
>   return thrift.PrependError("error writing set end: ", err)
>   }
>   if err := oprot.WriteFieldEnd(); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field end 
> error 4:taskIds: ", p), err)
>   }
>   return err
> }
> {noformat}
> So on the receiving end of the wire, a {{nil}} collection is turned into an 
> empty collection and so unset-ness cannot be distinguished from set but empty.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


[jira] [Commented] (THRIFT-3752) nil collections are serialized as empty collections

2016-03-23 Thread Jens Geyer (JIRA)

[ 
https://issues.apache.org/jira/browse/THRIFT-3752?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15209239#comment-15209239
 ] 

Jens Geyer commented on THRIFT-3752:


I don't know what you mean but the semantics of required, optional and default 
requiredness are quite clear. I agree on the docs part, at least some more 
details should be added to the web site. 

{quote}
The problem is in the serialization for the field, which wipes out the unset 
(nil) vs empty collection distinction at the wire level:
{quote}

If it is wrong (and after looking at your examples I very much tend to agree to 
that), then the logical conclusion is to fix it.

> nil collections are serialized as empty collections
> ---
>
> Key: THRIFT-3752
> URL: https://issues.apache.org/jira/browse/THRIFT-3752
> Project: Thrift
>  Issue Type: Bug
>  Components: Go - Compiler
>Reporter: John Sirois
>Assignee: John Sirois
>
> See discussion here: https://reviews.apache.org/r/45193/
> This is likely related to THRIFT-3700.
> In short, for this struct:
> {noformat}
> struct TaskQuery {
> 4: optional set taskIds
> }
> {noformat}
> The following go struct is generated:
> {noformat}
> type TaskQuery struct {
>   TaskIds  map[string]bool `thrift:"taskIds,4" json:"taskIds"`
> }
> {noformat}
> This is all well and good, since {{TaskQuery{}.TaskIds == nil}}; ie the 
> {{TaskIds}} collection field is - by default - unset.
> The problem is in the serialization for the field, which wipes out the unset 
> ({{nil}}) vs empty collection distinction at the wire level:
> {noformat}
> func (p *TaskQuery) writeField4(oprot thrift.TProtocol) (err error) {
>   if err := oprot.WriteFieldBegin("taskIds", thrift.SET, 4); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field begin 
> error 4:taskIds: ", p), err)
>   }
>   if err := oprot.WriteSetBegin(thrift.STRING, len(p.TaskIds)); err != 
> nil {
>   return thrift.PrependError("error writing set begin: ", err)
>   }
>   for v, _ := range p.TaskIds {
>   if err := oprot.WriteString(string(v)); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T. (0) field 
> write error: ", p), err)
>   }
>   }
>   if err := oprot.WriteSetEnd(); err != nil {
>   return thrift.PrependError("error writing set end: ", err)
>   }
>   if err := oprot.WriteFieldEnd(); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field end 
> error 4:taskIds: ", p), err)
>   }
>   return err
> }
> {noformat}
> So on the receiving end of the wire, a {{nil}} collection is turned into an 
> empty collection and so unset-ness cannot be distinguished from set but empty.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


[jira] [Commented] (THRIFT-3752) nil collections are serialized as empty collections

2016-03-23 Thread John Sirois (JIRA)

[ 
https://issues.apache.org/jira/browse/THRIFT-3752?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15208762#comment-15208762
 ] 

John Sirois commented on THRIFT-3752:
-

Hrm, so this may not be a thrift compiler bug per-se.  Marking 
{{TaskQuery.taskIds}} as optional yields:
{noformat}
type TaskQuery struct {
TaskIds  map[string]bool `thrift:"taskIds,4" 
json:"taskIds,omitempty"`
}

func (p *TaskQuery) IsSetTaskIds() bool {
return p.TaskIds != nil
}

func (p *TaskQuery) writeField4(oprot thrift.TProtocol) (err error) {
if p.IsSetTaskIds() {
if err := oprot.WriteFieldBegin("taskIds", thrift.SET, 4); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field begin error 
4:taskIds: ", p), err)
}
if err := oprot.WriteSetBegin(thrift.STRING, len(p.TaskIds)); err != 
nil {
return thrift.PrependError("error writing set begin: ", err)
}
for v, _ := range p.TaskIds {
if err := oprot.WriteString(string(v)); err != nil {
return thrift.PrependError(fmt.Sprintf("%T. (0) field write 
error: ", p), err)
}
}
if err := oprot.WriteSetEnd(); err != nil {
return thrift.PrependError("error writing set end: ", err)
}
if err := oprot.WriteFieldEnd(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field end error 
4:taskIds: ", p), err)
}
}
return err
}
{noformat}

The {{IsSetTaskIds}} method is new and its use to skip serialization for an 
unset {{taskIds}} field is what we want.

In other words, the thirft compiler for Go has a different notion of unset 
requiredness than the java compiler (The TaskQuery receiver in this case is the 
Aurora scheduler - written in java).  The perils of thrift's global lack of 
specificity as to how to handle optional vs required vs  is well 
documented and the real issue here :/.

[~jfarrell] Has there been any discussion of fixing this, declaring bankruptcy, 
or picking some other path to deal with incompatible behavior across the 
various language backends wrt requiredness?

> nil collections are serialized as empty collections
> ---
>
> Key: THRIFT-3752
> URL: https://issues.apache.org/jira/browse/THRIFT-3752
> Project: Thrift
>  Issue Type: Bug
>  Components: Go - Compiler
>Reporter: John Sirois
>Assignee: John Sirois
>
> See discussion here: https://reviews.apache.org/r/45193/
> This is likely related to THRIFT-3700.
> In short, for this struct:
> {noformat}
> struct TaskQuery {
> 4: optional set taskIds
> }
> {noformat}
> The following go struct is generated:
> {noformat}
> type TaskQuery struct {
>   TaskIds  map[string]bool `thrift:"taskIds,4" json:"taskIds"`
> }
> {noformat}
> This is all well and good, since {{TaskQuery{}.TaskIds == nil}}; ie the 
> {{TaskIds}} collection field is - by default - unset.
> The problem is in the serialization for the field, which wipes out the unset 
> ({{nil}}) vs empty collection distinction at the wire level:
> {noformat}
> func (p *TaskQuery) writeField4(oprot thrift.TProtocol) (err error) {
>   if err := oprot.WriteFieldBegin("taskIds", thrift.SET, 4); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field begin 
> error 4:taskIds: ", p), err)
>   }
>   if err := oprot.WriteSetBegin(thrift.STRING, len(p.TaskIds)); err != 
> nil {
>   return thrift.PrependError("error writing set begin: ", err)
>   }
>   for v, _ := range p.TaskIds {
>   if err := oprot.WriteString(string(v)); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T. (0) field 
> write error: ", p), err)
>   }
>   }
>   if err := oprot.WriteSetEnd(); err != nil {
>   return thrift.PrependError("error writing set end: ", err)
>   }
>   if err := oprot.WriteFieldEnd(); err != nil {
>   return thrift.PrependError(fmt.Sprintf("%T write field end 
> error 4:taskIds: ", p), err)
>   }
>   return err
> }
> {noformat}
> So on the receiving end of the wire, a {{nil}} collection is turned into an 
> empty collection and so unset-ness cannot be distinguished from set but empty.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)