https://github.com/gogo/protobuf لم يعد مسيطرًا على https://github.com/gogo/protobuf/issues/691 (حاليًا)
إنها تبعية ، والتي لا تتوافق مع الإصدار الجديد من golang/protobuf
، والذي تعتمد عليه المزيد والمزيد من الحزم ، وبالتالي نحتاج إلى استبدال الإصدار golang/protobuf
، اعتمادًا على الإصدارات القديمة من تبعياتنا المباشرة وربما حتى كسر الحزم بهذه الطريقة
التبعية gogo/protobuf
أوجد حلا لذلك
اكتشف ما إذا كان مشرف جديد سيظهر أم مكونًا إضافيًا مختلفًا مع تكافؤ الميزات؟
استخدم فقط الفانيليا بروتوبوف؟
الاختبارات
نعم
المكون الإضافي للتحقق الذي نستخدمه دعمًا تم إسقاطه لـ GoGo
https://github.com/envoyproxy/protoc-gen-validate/pull/340
أعتقد أن أفضل طريقة للمضي قدمًا هي اتباع النظام البيئي والهجرة بعيدًا عن gogo / protobuf. مع المزيد والمزيد من تبعياتنا الأخرى التي تبتعد عن gogo ، أعتقد أنه سيصبح من الصعب الاستمرار في استخدامه. بالطبع سيتطلب الهجرة الكثير من العمل ، لذلك إذا قمنا بذلك ، فنحن بحاجة إلى وضع خطة جيدة.
ربما يعرف rvolosatovs المزيد عن الخيارات المخصصة التي تم تعيينها في gogottn
، ولكن هذا ما وجدته للخيارات الواضحة في ملفاتنا الأولية:
gogoproto.customname
و gogoproto.stdtime
و gogoproto.stdduration
و goproto_enum_prefix
. هذه سهلة الإزالة نسبيًا ، لأن مترجم Go سيشتكي على الفور من أي مشاكل ناتجة.gogoproto.embed
أنه لم يعد بإمكاننا الوصول إلى الحقول المضمنة (سيساعدنا برنامج التحويل البرمجي Go في العثور عليها) ، وأن الرسائل لم تعد تفي ببعض الواجهات (قد يكون هذا أكثر صعوبة).gogoproto.nullable
مزيدًا من العمل ، لأنه سيتعين علينا البدء في استخدام المحاضر ، وإضافة شيكات صفرية. قد لا يتم اكتشاف المشكلات الناتجة بواسطة برنامج التحويل البرمجي Go. قد يكون الحل المحتمل هو جعل هذه الحقول خاصة مؤقتًا ، ثم إعادة الكتابة إلى الحاصلون / المحددون وأخيراً جعل الحقول عامة مرة أخرى.gogoproto.customtype
والتعدادات التي تستخدم خيارات gogoproto.enum_stringer
. بالنسبة لأولئك الذين غالبًا ما غيّرنا طريقة تنظيمهم / عدم تنظيمهم لـ JSON. بالنسبة للحقول المخصصة bytes
مثل EUI و DevAddr وما إلى ذلك ، يمكننا تغيير النوع (في الرسائل الأولية) إلى string
(وهو متوافق مع النظام الثنائي). مع التعدادات أخشى أن يتم كسر واجهة برمجة تطبيقات JSON ، حيث يتم قبولها الآن (بواسطة UnmarshalJSON) كسلاسل و ints.ربما يكون هذا أيضًا وقتًا مناسبًا لبدء التفكير في الإصدار 4 API الخاص بنا ، لأنني أستطيع أن أتخيل أننا قد نكتشف المزيد من المفاجآت (كسر واجهة برمجة التطبيقات).
أعتقد أن أفضل طريقة للمضي قدمًا هي تجربة https://github.com/alta/protopatch أولاً
api
)protopatch
إذا كان ميزة منخفضة الجهد. هذا يعتمد حقًا على الخيار ، على الرغم من - إذا كنا نتحدث عن customtype
- فإن IMO تبرر بالتأكيد المساهمة ، ولكن ربما شيء مثل stdtime
- ليس كثيرًا.بالنظر إلى المستقبل ، لا أعتقد أننا يجب أن نستخدم بروتوس الفانيليا بروتوبوف مباشرة في المكونات داخليًا في وقت التشغيل (بالنظر إلى مجموعة الميزات المقدمة من protobuf اليوم).
من المنطقي فقط استخدام protobuf للتسلسل (de-) ، لذلك للتخزين وعلى طبقة API. داخليًا ، ومع ذلك ، فإن استخدام بروتوس Go التي تم إنشاؤها بواسطة الفانيليا ليس منطقيًا بالنسبة لي.
لذلك ، على سبيل المثال ، NS:
*ttnpb.EndDevice
(نوع Go الذي تم إنشاؤه بواسطة الفانيليا) من التسجيل ، مع إلغاء التسلسل من البيانات الثنائية المخزنة*ttnpb.EndDevice
إلى T_device
، (ملاحظة: ربما يكون هذا مجرد غلاف في البداية أو إلى الأبد)T_device
داخليًا في NST_device
إلى *ttnpb.EndDevice
(ملاحظة: قد تكون هذه مهمة تافهة وسريعة جدًا إذا كنا نستخدم غلافًا ، نظرًا لأننا نحتاج فقط إلى تعديل الحقول التي تم تغييرها ويمكن تنفيذ ذلك على ثنائي البيانات مباشرة)*ttnpb.EndDevice
، التسلسل في البيانات الثنائيةالمراجع أيضًا https://github.com/TheThingsNetwork/lorawan-stack/issues/342 (السكان الذين تم إنشاؤهم)
أنا لا أؤيد البديل (الأصغر) لـ gogo. إنه شعور مثل دفع العلبة. دعونا نحافظ على الأشياء بأكبر قدر ممكن من الفانيليا ، خاصة عندما نحتاج إلى أن نقرر مرة أخرى أفضل طريقة للمضي قدمًا.
أوافق على أنه يمكننا التفكير في استخدام أنواع وسيطة في بعض الأماكن ، بدلاً من الاعتماد في كل مكان على البروتوس التي تم إنشاؤها. إنه يفصل أساسًا كائنات نقل البيانات (DTOs: protos ، أيضًا للتخزين) عن كائنات الوصول إلى البيانات (DAOs: كيف نستخدمها). إذا كان هذا هو القراءة في المقام الأول ، فيمكننا أيضًا إعلان الواجهات ومعرفة المدى الذي وصلنا إليه في ذلك.
ومع ذلك ، لن أذهب إلى حد تغيير NS بالكامل لاستخدام T_device
، ولكن بالأحرى هياكل و / أو واجهات محددة حسب الحاجة.
دعنا ننتقل هذه المناقشة إلى نوفمبر
rvolosatovs ما هو اعتراضك على الانتقال إلى الفانيليا مع منظم JSON المخصص؟
عبء الترحيل الهائل والأحمال من النموذج المعياري إذا انتهى بنا الأمر فقط باستخدام بروتوس الفانيليا مباشرة.
أنا لا أعترض على ذلك حقًا ، لكني أعتقد أننا يجب أن نحاول إيجاد بديل بسيط غير تدخلي أولاً ، وإذا لم يكن ذلك ممكنًا ، فقم بإعادة صياغة هذا الأمر برمته.
أخشى أن أي مكون إضافي نبدأ في الاعتماد عليه سينتهي به الأمر في حالة غير صيانة في مرحلة ما. بشكل عام ، أنا أؤيد إبقاء الأشياء قريبة من الفانيليا قدر الإمكان. إذا كان هذا يعني أن التحقق من nil
أكثر مما نود ، فليكن. يمكن أيضًا أن يكون لصالحنا أننا نعلم أن الأشياء لم يتم ضبطها ، بدلاً من هيكل مُهيأ.
أخشى أن إعادة هيكلة قاعدة الكود الخاصة بنا بالكامل ستكون بمثابة ألم بغض النظر عن كيفية قيامنا بذلك. تُستخدم الهياكل الأولية (التي تم إنشاؤها بواسطة gogo) في كل مكان في الوقت الحالي (واجهة برمجة تطبيقات gRPC ، وواجهة برمجة تطبيقات HTTP ، والأحداث ، والأخطاء ، داخليًا ، و Redis DB ، ...) ، لذا فإن التغيير إلى شيء آخر (أيًا كان هذا الشيء الآخر) سوف يمس إلى حد كبير كل شيء في قاعدة الشفرة لدينا ، والطريقة التي تبدو بها الآن ، كلها في نفس الوقت.
الشرط الصعب هو أننا لا نكسر توافق v3 API الخاص بنا. حتى إذا قررنا استخدام هذا الموقف كلحظة لبدء العمل على v4 API (داخليًا على الأقل) ، فلا يزال يتعين علينا الاستمرار في دعم v3 API للمستخدمين الحاليين.
على المدى الطويل ، أعتقد أننا سنفعل لأنفسنا خدمة كبيرة من خلال فصل واجهات برمجة التطبيقات الخارجية (التي تم إصدارها ، والمستقرة داخل الشركة الرئيسية) من واجهة برمجة التطبيقات (غير المنفردة ، والمستقرة داخل القاصر) الخاصة بنا ووثائق قاعدة البيانات (ذات الإصدار الثابت ، والمستقرة) . يمكننا بعد ذلك كتابة أو إنشاء وظائف للتحويل بين واجهات برمجة التطبيقات الداخلية الخاصة بنا والآخرين.
لكني أعتقد أن هناك بعض الخطوات التي يمكننا اتخاذها الآن:
من أجل الحفاظ على توافق v3 JSON API الخاص بنا ، أعتقد أن TODO الأول لدينا هو العمل على إنشاء منظمي JSON و unmarshalers الذين يفهمون كيفية تنظيم / إلغاء تنظيم أنواعنا المخصصة. أعتقد أن القيام بذلك أمر ذكي على أي حال لأنه لا يوجد وعد بالاستقرار لتنفيذ Go لتنسيق JSON لمخازن البروتوكول المؤقتة ، لذلك من الأفضل أن نتحكم في ذلك بأنفسنا. يمكن أن يسمح لنا القيام بذلك أيضًا بالنظر في أقنعة المجال عند التنظيم إلى JSON. في وقت التشغيل grpc-gateway
يمكننا تسجيل برامج الترميز ، لذا يمكننا فقط كتابة برنامج ترميز يستدعي منظمينا (المُنشأ) (un) بدلاً من {gogo، golang} / protobuf's jsonpb.
لقد جربت ذلك بالفعل هنا: https://github.com/TheThingsNetwork/lorawan-stack/commit/a41f62d98ae7ee719b576e6fcd2009a79cd38f4c
هذا يجعل protobuf يشكو من أنواع التسجيل ، لذلك قد نحتاج إلى إزالة golang_proto.RegisterType
من البروتوس القديم لدينا لجعل هذا العمل. قد تؤدي إزالة ذلك إلى كسر حل google.protobuf.Any
، لكننا نستخدمها فقط في الأخطاء والأحداث ، لذلك يمكننا على الأرجح إيجاد حلول لهذه الحالات المحددة.
هذا خاص بالفترة الانتقالية فقط ، ولكن بالنسبة للحل طويل المدى ، نود إنشاء محولات مماثلة.
لقد جربت ذلك بالفعل من خلال خدمة بسيطة هنا: https://github.com/TheThingsNetwork/lorawan-stack/commit/cd7d75c8b42ad15eee1ac594ff6d0f2d5a75eb67 ، ولكن بالنسبة للخدمات الأكثر تعقيدًا ، سنحتاج بالتأكيد إلى تلك المحولات.
لاحظ أن هذا يغير فقط خدمة grpc نفسها. لا تزال بوابة grpc تستخدم عناصر gogo القديمة على جانب JSON ، ثم تستدعي خادم gRPC الداخلي ، والذي يقوم بعد ذلك بتشغيل التنفيذ الجديد.
دفع بعض تحديثات التبعية الأولية وحلول التوافق العكسي هنا: https://github.com/TheThingsNetwork/lorawan-stack/compare/issue/2798-codec
يتم ترقية المزيد والمزيد من تبعياتنا إلى protobuf 1.4 و V2 API ، وكلما طالت مدة بقاءنا مفتوحًا ، زادت المشكلات التي سنواجهها عند محاولة ترقية تبعياتنا.
يجب أن نعطي هذا أولوية أكبر وأن نتخذ قرارًا بشأن ما سنفعله حيال كل هذا.
يرجى التخطيط لمكالمة للأسبوع المقبل حتى نتمكن من مناقشتها في وضع عدم الاتصال.
أعتقد أننا يجب أن نمر بعملية الألم هذه والتركيز على حلها في غضون أسبوع أو أسبوعين. ولتجنب ذلك نقوم بأشياء أخرى لأن هذا سيؤدي إلى الكثير من الصراعات بخلاف ذلك. يتطلب امتلاك أكبر عدد ممكن من الأيدي معرفة ما سنفعله بالضبط في أي الحالات ، وتقسيم المهام قدر الإمكان ، ومراقبة الجائزة.
الخطوات التالية:
unconvert
و gofumpt
وأي شيء آخر نقوم به بالإضافة إلى protocprotoc-gen-gogottn
إلى protoc-gen-gofast
(أو أيًا كان ما هو قريب من الفانيليا)(gogoproto.*)
صريح في ملفات proto الخاصة بنا ، بحيث يتم عرضها كما هو الحال الآنgopls
و rf
هذا الأمر.(gogoproto.*)
واحدًا تلو الآخر وتحديث الكود الذي يستخدمه. ربما تساعد أدوات مثل gopls
و rf
هذا الأمر.gogoproto.populate
وتحديث الاختبارات (https://github.com/TheThingsNetwork/lorawan-stack/issues/342)gogoproto.customname
وتغيير EUI -> Eui
إلخ.gogoproto.embed
. نحتاج إلى التأكد من أن الرسائل لا تزال تستخدم واجهات مثل ValidateContext(context.Context) error
و ExtractRequestFields(m map[string]interface{})
.gogoproto.nullable
والتأكد من أننا نستخدم Getters حيثما أمكن ذلك ، ونقوم بشيكات صفرية بخلاف ذلك.rvolosatovs دعونا نحاول القيام بهذه الخطوات الأولى للإصدار 3.11.3. عند الانتهاء من ذلك ، يرجى إعادة إضافة المحال إليهم الآخرين ، ودعنا نناقش مرة أخرى.
التعليق الأكثر فائدة
يرجى التخطيط لمكالمة للأسبوع المقبل حتى نتمكن من مناقشتها في وضع عدم الاتصال.
أعتقد أننا يجب أن نمر بعملية الألم هذه والتركيز على حلها في غضون أسبوع أو أسبوعين. ولتجنب ذلك نقوم بأشياء أخرى لأن هذا سيؤدي إلى الكثير من الصراعات بخلاف ذلك. يتطلب امتلاك أكبر عدد ممكن من الأيدي معرفة ما سنفعله بالضبط في أي الحالات ، وتقسيم المهام قدر الإمكان ، ومراقبة الجائزة.