-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor PagedDoraWorker by injecting MetaManager and UfsManager #18181
Conversation
Automated checks report:
Some checks failed. Please fix the reported issues and reply 'alluxio-bot, check this please' to re-run checks. |
2fec0ec
to
b597c61
Compare
4ff13c3
to
28ad411
Compare
@@ -57,7 +57,7 @@ public void before() throws IOException { | |||
PagedDoraWorker worker = mock(PagedDoraWorker.class); | |||
CacheManager cacheManager = mock(CacheManager.class); | |||
mDoraUfsManager = mock(DoraUfsManager.class); | |||
mManager = new DoraMetaManager(conf, worker, cacheManager, mDoraUfsManager); | |||
mManager = new DoraMetaManager(conf, cacheManager, mDoraUfsManager); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this line is one of the core change in this PR. The PagedDoraWorker no longer passes its this
out in its own constructor. The this
ref escaping in the constructure is a bad practice we should avoid.
super(ExecutorServiceFactories.fixedThreadPool("dora-worker-executor", 5)); | ||
mWorkerId = workerId; | ||
mConf = conf; | ||
mUfsManager = mResourceCloser.register(new DoraUfsManager()); | ||
mUfsManager = mResourceCloser.register(ufsManager); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just creating the UfsManager outside this constructor and passing it in. The code logic does not change at all so this refactor should be effectively minor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guice advises against injecting closeable resources especially when it's a singleton, as it's hard to reason about who is responsible to close the resource. https://github.com/google/guice/wiki/Avoid-Injecting-Closable-Resources
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea for best coding style we probably should refactor this a bit (together with our next big modularization efforts).
For the current code, PagedDoraWorker.close()
is the end of worker process and I figure it's fine we let the closer close that singleton.
@@ -209,8 +201,7 @@ protected PagedDoraWorker( | |||
mPageSize = mConf.getBytes(PropertyKey.WORKER_PAGE_STORE_PAGE_SIZE); | |||
mBlockMasterClientPool = blockMasterClientPool; | |||
mCacheManager = cacheManager; | |||
mMetaManager = mResourceCloser.register( | |||
new DoraMetaManager(mConf, this, mCacheManager, mUfsManager)); | |||
mMetaManager = mResourceCloser.register(metaManager); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interestingly, I don't have something like bind(MetaManager).to(DoraMetaManager.class)
in DoraWorkerModule
and Guice is actually able to notice that and create the MetaManager
instance for me. Is that okay? I figure we should always call bind()
explicitly in code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DoraMetaManager
is not an interface but a concrete class. There is no MetaManager
.
* @param xattrMap | ||
* @return a FileInfo | ||
*/ | ||
public alluxio.grpc.FileInfo buildFileInfoFromUfsStatus(UfsStatus status, String ufsFullPath, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two methods are just changed static
and moved to the end of this file.
// Create FileSystemContext shared across all worker components | ||
FileSystemContext fileSystemContext = FileSystemContext.create(); | ||
bind(FileSystemContext.class).toInstance(fileSystemContext); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the change in PagedDoraWorker constructor, I'm just moving some resource creation out of PagedDoraWorker()
into this module definition, and injecting into the constructor. The code logic effectively doesn't change.
dora/core/server/worker/src/main/java/alluxio/worker/dora/PagedDoraWorker.java
Show resolved
Hide resolved
blockWorkerService = | ||
new DoraWorkerClientServiceHandler((DoraWorker) dataWorker); | ||
new DoraWorkerClientServiceHandler((PagedDoraWorker) dataWorker); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DoraWorker
interface is missing a lot of method definitions so we need to downcast in DoraWorkerClientServiceHandler
after all. So I'm just casting to the real class to avoid the frequent casting.
// TODO(lucy) change to string typed once membership manager got enabled by default | ||
private final AtomicReference<WorkerIdentity> mWorkerId; | ||
protected final CacheManager mCacheManager; | ||
protected final DoraUfsManager mUfsManager; | ||
private final DoraMetaManager mMetaManager; | ||
protected final UfsManager mUfsManager; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use interface here since we are using dependency injection. If one method is not defined on the interface (in the concrete class), I'm moving the signature to the interface level.
protected final DoraUfsManager mUfsManager; | ||
private final DoraMetaManager mMetaManager; | ||
protected final UfsManager mUfsManager; | ||
protected DoraMetaManager mMetaManager; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's necessary to change the scope here so a child class can see this field
* @param xattrMap | ||
* @return a FileInfo | ||
*/ | ||
public static alluxio.grpc.FileInfo buildFileInfoFromUfsStatus( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's probably a better place for these 2 static methods but I don't see it right now
Automated checks report:
All checks passed! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
alluxio-bot, merge this please |
alluxio-bot, cherry-pick this to branch-3-1.1.x please |
Auto cherry-pick to branch |
### What changes are proposed in this pull request? 1. If an object is created inside `PagedDoraWorker` constructor, extract that creation to before the constructor and use dependency injection to inject it to the worker object. This doesn't change any creation logic, just a refactor to better adapt to dependency injection flavor. 2. There is a circular dependency between `MetaManager` and `PagedDoraWorker`. This change removes that cycle. Now we create one, then create the other. Before, we create one and in the construction, we let `this` ref escape and create the other. Some methods are either moved or changed to `static`. 3. By adapting to dependency injection, we rely on `UfsManager` interface instead of `DoraUfsManager` implementation. Some method signatures are extracted to the interface level. 4. A few other small refactors to get rid of some downcasts and variable scope changes. Reasons are attached in comments on this PR. ### Why are the changes needed? Improve code quality and extensibility. ### Does this PR introduce any user facing changes? No. All refactor changes are small and equivalent to existing code. So nothing should break. pr-link: #18181 change-id: cid-4f9e9bc770b12253188bb541dd456ef3cd889c2b
Cherry-pick of existing commit. orig-pr: #18181 orig-commit: 0e83207 orig-commit-author: Jiacheng Liu <[email protected]> pr-link: #18381 change-id: cid-4f9e9bc770b12253188bb541dd456ef3cd889c2b
### What changes are proposed in this pull request? 1. If an object is created inside `PagedDoraWorker` constructor, extract that creation to before the constructor and use dependency injection to inject it to the worker object. This doesn't change any creation logic, just a refactor to better adapt to dependency injection flavor. 2. There is a circular dependency between `MetaManager` and `PagedDoraWorker`. This change removes that cycle. Now we create one, then create the other. Before, we create one and in the construction, we let `this` ref escape and create the other. Some methods are either moved or changed to `static`. 3. By adapting to dependency injection, we rely on `UfsManager` interface instead of `DoraUfsManager` implementation. Some method signatures are extracted to the interface level. 4. A few other small refactors to get rid of some downcasts and variable scope changes. Reasons are attached in comments on this PR. ### Why are the changes needed? Improve code quality and extensibility. ### Does this PR introduce any user facing changes? No. All refactor changes are small and equivalent to existing code. So nothing should break. pr-link: Alluxio#18181 change-id: cid-4f9e9bc770b12253188bb541dd456ef3cd889c2b
What changes are proposed in this pull request?
PagedDoraWorker
constructor, extract that creation to before the constructor and use dependency injection to inject it to the worker object. This doesn't change any creation logic, just a refactor to better adapt to dependency injection flavor.MetaManager
andPagedDoraWorker
. This change removes that cycle. Now we create one, then create the other. Before, we create one and in the construction, we letthis
ref escape and create the other. Some methods are either moved or changed tostatic
.UfsManager
interface instead ofDoraUfsManager
implementation. Some method signatures are extracted to the interface level.Why are the changes needed?
Improve code quality and extensibility.
Does this PR introduce any user facing changes?
No. All refactor changes are small and equivalent to existing code. So nothing should break.