Re: json parsing/decoding

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Feb 6, 2013 at 4:53 PM, Sage Weil <sage@xxxxxxxxxxx> wrote:
> On Wed, 6 Feb 2013, Yehuda Sadeh wrote:
>> On Wed, Feb 6, 2013 at 2:23 PM, Sage Weil <sage@xxxxxxxxxxx> wrote:
>> > On Wed, 6 Feb 2013, Yehuda Sadeh wrote:
>> >> The matter of json decoding was brought up as part of the discussion
>> >> of the ceph management api. I recently had to deal with it with the
>> >> rados gateway, as I wasn't too happy was the current mechanisms that
>> >> were used for this purpose. So I introduced a new decode_json()
>> >> functionality (now in common/ceph_json.* at the wip-json-decode
>> >> branch). It's very similar to the regular encode/decode stuff that we
>> >> use to encode/decode structures. Encoding is being done using the
>> >> already existing dump() method, and decoding will be done through the
>> >> new decode_json() method.
>> >>
>> >> As an example we'll define a new UserInfo structure:
>> >>
>> >> struct UserInfo {
>> >>   string uid;
>> >>   string display_name;
>> >>   int max_buckets;
>> >>   list<Key> keys;
>> >>
>> >>   void dump(Formatter *f) const;
>> >>   void decode_json(JSONObj *obj);
>> >> };
>> >>
>> >> The dump() method will look like this:
>> >>
>> >> void UserInfo::dump(Formatter *f) const
>> >> {
>> >>   f->open_object_section("user_info");
>> >>   f->dump_string("user_id", uid);
>> >>   f->dump_string("display_name", display_name);
>> >>   f->dump_int("max_buckets", (int)max_buckets);
>> >>
>> >>   f->open_array_section("keys");
>> >>   for (list<Key>::iterator iter = keys.begin(); siter != keys.end(); ++iter) {
>> >>     iter->dump(f);
>> >>   }
>> >>   f->close_section();
>> >>
>> >>   f->close_section();
>> >> }
>> >>
>> >> It is recommended that every dump() method opens an object section and
>> >> puts everything within, so that every object could be easily embedded
>> >> within other objects. We can also probably create some template that
>> >
>> > The current loose convention is that the dump objects do not define the
>> > container they dump into.  It's a bit weird, but it lets you do things
>> > like:
>> >
>> > map<Key, Value> foo;
>> >
>> >    f->open_array_section("keys");
>> >    for (map<Key,Value>::iterator iter = keys.begin(); siter != keys.end(); ++iter) {
>> >      f->open_object_section("thing");
>> >      f->dump_string("key", iter->first);
>> >      iter->second.dump(f);
>> >      f->close_section();
>> >    }
>> >    f->close_section();
>> >
>> > Admittedly that doesn't come up *that* often, but it happened enough when
>> > we first started doing the dump stuff that all/most of the dumpers work
>> > that way.
>> >
>> > How should we deal with that?
>> >
>>
>> Modify the dumpers to not work this way? It's a matter of conventions,
>> not set in stone. If we keep this form then we'd need to create
>> decoders for these records:
>>
>> struct KeyRecord {
>>   Key k;
>>   Value v;
>>
>>   void decode_json(JSONObj *obj) {
>>     JSONDecoder::decode_json("key", key, obj);
>>     v.decode_json(obj);
>>   }
>> };
>>
>> This will work, assuming Value doesn't have any field indexed by "key".
>
> I think it mostly comes up in dumping other structures, not parsing, so it
> may be mostly ok on that end. I'm not sure how to manage dumping, though,
> if the section is opened inside the value object's dump().
>
> This also worries me: ceph_dencoder does
>
>       jf.open_object_section("object");
>       den->dump(&jf);
>       jf.close_section();
>
> which means that this sort of change will probably the type
> encoding/decode unit tests we run.
>
> Maybe something like
>
> void encode_json(Formatter *f) const
> {
>   f->open_object_section("mytype");
>   dump(f);
>   f->close_section();
> }
>
> will give us the cleaner interface you're looking for.  And the

Yeah.

> ceph-dencoder type definitions can mark types which implement one or the
> other... or we can implement the encode_json one for all objects as a
> wrapper via a macro or something we don't have to duplicate teh
> boilerplate everywhere?
>
That's one option. Not sure if I like the idea of doing it through a
macro, but it's solvable anyway.

Yehuda
--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [CEPH Users]     [Ceph Large]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux