Page MenuHomePhabricator

[services] Backup - Implementation update
ClosedPublic

Authored by karol on Feb 18 2022, 5:02 AM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Apr 23, 5:09 PM
Unknown Object (File)
Tue, Apr 23, 5:09 PM
Unknown Object (File)
Tue, Apr 23, 5:09 PM
Unknown Object (File)
Tue, Apr 23, 5:09 PM
Unknown Object (File)
Tue, Apr 23, 5:09 PM
Unknown Object (File)
Tue, Apr 23, 5:09 PM
Unknown Object (File)
Tue, Apr 23, 5:09 PM
Unknown Object (File)
Tue, Apr 23, 5:09 PM

Details

Summary

Update the implementation so it uses the base reactor from D3246.

Also, we edit the proto file so we can use the base reactor for one-direction streams.

Depends on D3246

Test Plan
cd services
yarn run-backup-service

Diff Detail

Repository
rCOMM Comm
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

squashed commmit which edited proto file in here

karol edited the test plan for this revision. (Show Details)
karol added reviewers: tomek, max, varun, jim.
karol edited the test plan for this revision. (Show Details)
tomek requested changes to this revision.Feb 22 2022, 4:30 AM

Is it a good practice to create a new class every time a method is invoked? I would guess, we should declare classes outside, construct objects in methods and return the instances. What is the reason behind taking your approach?

This revision now requires changes to proceed.Feb 22 2022, 4:30 AM

I'm not sure about this. I looked around a bit and have not found any information about this. Basically, local classes can be used and I've not seen any big issues with it.

tomek requested changes to this revision.Feb 23 2022, 9:51 AM
In D3248#87324, @karol-bisztyga wrote:

I'm not sure about this. I looked around a bit and have not found any information about this. Basically, local classes can be used and I've not seen any big issues with it.

Even when this is a valid language construction, we need to check if it should be used in this context. And currently, it looks like there are no benefits of using this approach compared to an alternative approach.
Currently we have four template methods, with two type parameters and one argument. In each of these methods, we create a local class that uses template type parameters when determining its parent class. None of the classes use function parameter context. So at this point, each of inner classes could be moved outside the function and all the code would compile and work the same.

So at the moment, defining the classes locally has only one advantage: we don't allow anyone to instantiate them outside the function - if that was the intention, then we can consider keeping this approach.

Local classes can be extremely useful when their definition depends on function argument. Currently it's not the case, but maybe this is going to change. What is the plan for these? (even if the code depends on the argument, it could as well be passed to the constructor, though)

To summarize, could you explain why local classes were used in this case? There exist some valid reasons, but at this point this code could be simplified to use normal classes, so I'm wondering what is the plan here.

This revision now requires changes to proceed.Feb 23 2022, 9:51 AM

Yes, the fact that these classes cannot be used outside of these functions is one thing. Another is that we have the implementations in one place. For me, it's easier to read. Please note that these classes contain just one method with the logic, maybe some of them will have some simple state.

Honestly, I do not think this is very important, we can move these classes somewhere, I find them better where they are, it indicates explicitly that they're supposed to be used only in this one specific place, plus we have a code with the logic directly inside of these functions.

I prefer this as is. I assume you prefer the opposite. I guess the fastest option to move forward here is to get an opinion of someone else and proceed with the outcome.

@geekbrother @varun @jimpo @atul

tomek requested changes to this revision.Feb 24 2022, 7:57 AM

I prefer this as is. I assume you prefer the opposite.

It's not that I have a strong preference for one solution or another. But I do have preference to use the default approach unless there are good reasons to use something different.

the fact that these classes cannot be used outside of these functions is one thing

Agree, this is a valid point

Another is that we have the implementations in one place

Also a good point. But if we created normal classes in this file, it would be also in one place.

For me, it's easier to read

This surprised me. For me it's a lot worse to read. We have a couple of levels of additional indentation - and our experience from CommCoreModule suggests that this is a real issue.
If a local class is short, then the readability would be ok, but here it looks like the opposite will be true.

Please note that these classes contain just one method with the logic, maybe some of them will have some simple state.

That makes sense. We can't use static members inside them but simple state would be ok.

I find them better where they are, it indicates explicitly that they're supposed to be used only in this one specific place, plus we have a code with the logic directly inside of these functions.

Why should they be used only here? Is there something which makes them unusable in other places?

I guess the fastest option to move forward here is to get an opinion of someone else and proceed with the outcome.

I'm not going to block you on this as it looks like you think your approach is better here. I only wanted to hear why is that.

Requesting changes to clarify core dumps issue

services/backup/docker-server/contents/server/src/BackupServiceImpl.cpp
49–51 ↗(On Diff #9834)

Could you describe when such core dumps are possible? How can making the response a member of a class help?

This revision now requires changes to proceed.Feb 24 2022, 7:57 AM

Ok, thanks. I think we can leave it as is and in a case, the classes grow too much we can move them outside of functions(or for any other reason later on).

Why should they be used only here? Is there something which makes them unusable in other places?

Every one of these classes is created specifically for one grpc call. I don't see any other use cases for them honestly but I may be wrong.

services/backup/docker-server/contents/server/src/BackupServiceImpl.cpp
49–51 ↗(On Diff #9834)

authResponse is a local variable and we're passing it as a ref. Since it's allocated on the stack, once it goes out of scope it will get deallocated. I just wanted the code to compile, didn't test the runtime anyway, but we should address this issue when we'll be implementing and testing the code, that's why I added this comment.

tomek requested changes to this revision.Feb 25 2022, 1:44 AM
tomek added inline comments.
services/backup/docker-server/contents/server/src/BackupServiceImpl.cpp
49–51 ↗(On Diff #9834)

The code that compiles but fails in runtime is risky - we might forget about it by mistake. I would prefer deleting or commenting this code out.
And generally, we should avoid putting up the diffs with code that is untested. In 3 remaining functions the implementation is empty and TODO comment is included. If we know that this code always fails, why can't we do the same here?

The issue with this approach is that, when a new diff is created, it will somehow modify this code and we would still need to review the code from this diff because currently we know that this doesn't work. It's a lot better when we can clearly differentiate between code that is correct and that isn't. So in this case, we would save ourselves a lot of time, if all the invalid code was replaced by TODO. My guess is that this is only this line and the checks from above can safely stay.

This revision now requires changes to proceed.Feb 25 2022, 1:44 AM
services/backup/docker-server/contents/server/src/BackupServiceImpl.cpp
49–51 ↗(On Diff #9834)

ok im gonna delete whats below, the point here is to show how more or less the auth manager is supposed to be used.

This revision is now accepted and ready to land.Feb 25 2022, 3:24 AM
This revision now requires review to proceed.Feb 25 2022, 3:24 AM
karol added inline comments.
native/cpp/CommonCpp/grpc/protos/backup.proto
9 ↗(On Diff #9924)

This should be reverted. It will be possible to implement one-way stream once I do this task

using read reactor for send log

ashoat edited reviewers, added: atul; removed: ashoat. ashoat added 1 blocking reviewer(s): varun.

@varun and @atul should review this, they have context on this BiDi reactor stuff and I do not

Approving because this looks right to me, but I don't have much context on the backup service nor do I have much experience with templates in C++... so keep that in mind

I know @palys-swm already approved, but maybe he can take a final look before landing?

services/backup/docker-server/contents/server/src/BackupServiceImpl.cpp
50–51 ↗(On Diff #10021)

I think this comment was supposed to be deleted?

From above: "ok im gonna delete whats below, the point here is to show how more or less the auth manager is supposed to be used."

This revision is now accepted and ready to land.Mar 9 2022, 9:02 PM

return pointer from processRequest

services/backup/docker-server/contents/server/src/BackupServiceImpl.cpp
50–51 ↗(On Diff #10021)

Yes, basically protobuf takes care of deleting the object so it's okay to allocate memory for it dynamically and pass a pointer to a set_allocated_ method. I refactored the code so we create pointers.