Add implementation for clearing cache table#177
Add implementation for clearing cache table#177hjk1030 wants to merge 19 commits intoddkang:mainfrom
Conversation
|
By the way, do I need to add tests for this? |
Yes. |
|
I modified an existing test to validate this since adding another test makes the existing test fail. |
| for service_binding in engine._config.inference_bindings: | ||
| if isinstance(service_binding, CachedBoundInferenceService): | ||
| async with service_binding._engine.begin() as conn: | ||
| stmt = delete(service_binding._cache_table) |
There was a problem hiding this comment.
use meaningful variable names
| await conn.execute(stmt) | ||
| tables = service_binding.get_tables(service_binding.binding.output_columns) | ||
| for table_name in tables: | ||
| stmt = delete(service_binding._tables[table_name]._table) |
There was a problem hiding this comment.
If tables have dependencies, does deleting them in any arbitrary order cause issues?
(e.g. table B has a foreign key that refers to table A, does deleting table A first cause an issue?)
tests/tests_caching_logic.py
Outdated
| from tests.inference_service_utils.http_inference_service_setup import run_server | ||
| from tests.utils import setup_gt_and_aidb_engine, setup_test_logger | ||
| from aidb.utils.asyncio import asyncio_run | ||
| from aidb_utilities.db_setup.clear_cache import clear_ML_cache |
launch.py
Outdated
| from aidb_utilities.db_setup.create_tables import create_output_tables | ||
| from aidb.utils.asyncio import asyncio_run | ||
|
|
||
| from aidb_utilities.db_setup.clear_cache import clear_ML_cache |
tests/tests_caching_logic.py
Outdated
| # running the same query, so number of inference calls should remain same | ||
| # temporarily commenting this out because we no longer call infer_one | ||
| assert aidb_engine._config.inference_services["objects00"].infer_one.calls == calls[index] | ||
| assert aidb_engine._config.inference_services["objects00"].infer_one.calls == calls[index][0], f"Wrong query count: Expected {calls[index][0]}, Actual {aidb_engine._config.inference_services['objects00'].infer_one.calls}" |
There was a problem hiding this comment.
This line is too long. Maximum line length is 80 characters.
|
I modified the code style. Also changes the delete order to depend on foreign key references. |
| Clear the cache table at start if the ML model has changed. | ||
| Delete the cache table for each service. | ||
| ''' | ||
| for inference_binding in engine._config.inference_bindings: |
There was a problem hiding this comment.
Can you refactor the code?
- Collect all tables.
- Construct a Table Graph
- topological sort
- Delete tables.
You can refer toand https://github.com/ddkang/aidb/blob/d8e78e488ac91b78e8cc002b06aa01dfa8f39dfd/aidb/config/config.py#L121C23-L121C39Line 65 in d8e78e4
|
@ttt-77 Could you please review this PR again? |
| @@ -1,13 +1,18 @@ | |||
| from multiprocessing import Process | |||
| import os | |||
There was a problem hiding this comment.
Have you added this test to Github Action?
There was a problem hiding this comment.
Yes. The test is modified based on an original test and I verified it is executed.
|
Looks good to me. @ddkang |
|
|
||
|
|
||
| async def clear_ML_cache(engine: Engine): | ||
| ''' |
There was a problem hiding this comment.
Use standard naming conventions "clear_ml_cache"
There was a problem hiding this comment.
Also why is this in the DB setup and not the engine?
| ''' | ||
| Clear the cache table at start if the ML model has changed. | ||
| Delete the cache table for each service. | ||
| ''' |
* Move the clear cache function to engine * Function name change * Add code logic comment
tests/tests_caching_logic.py
Outdated
| @@ -47,24 +51,35 @@ async def test_num_infer_calls(self): | |||
| # no service calls before executing query | |||
There was a problem hiding this comment.
We should have a separate test that tests that other ML models don't get removed when one is removed
* Add deletion for services seperately * Fix launch.py * Add test to check whether only cache for one service is deleted
* Change function param declaration to be compatible with python 3.8 * Change call count logic since all the inference service use the same counter * Add join() function to terminate the test server completely
* Clear cache before test run * Set count target corresponding to initial call count
* run cache clearing using asyncio
* Fix typo
* Add join() and sleep to make sure the server terminates
|
@ddkang Could you please review this? |
| del gt_engine | ||
| del aidb_engine | ||
| p.terminate() | ||
| p.join() |
There was a problem hiding this comment.
Also, I cannot terminate the test server completely without this. I'm not sure whether it's a bug or I'm not using the correct way to write multiple tests.
There was a problem hiding this comment.
I believe the test server wasn't properly closed before. The server will still occupy the port if only the terminate() function is called. However most test classes only have one unit test or the service is not called, so it did not cause any problems.
aidb/engine/engine.py
Outdated
| finally: | ||
| self.__del__() | ||
|
|
||
| async def clear_ml_cache(self, service_name_list = None): |
There was a problem hiding this comment.
Is there a reason this function is so complicated?
There was a problem hiding this comment.
Most of this function is building the foreign key relationship graph since deleting the data referenced by another output table will cause error. I believe this is necessary unless there exists such a graph already.
There was a problem hiding this comment.
Are there other functions that build the fk relationship graph? If so, that should be refactored
* Use the existing inference topological order as delete order
|
I refactored the function using the topological order of inference services. |
|
@ttt-77 please check |
aidb/engine/engine.py
Outdated
| if isinstance(bounded_service, CachedBoundInferenceService): | ||
| if bounded_service.service.name in service_name_list: | ||
| for input_column in bounded_service.binding.input_columns: | ||
| service_name_list.add(input_column.split('.')[0]) |
There was a problem hiding this comment.
why do you add table name into service_name_list?
aidb/engine/engine.py
Outdated
| service_name_list.add(input_column.split('.')[0]) | ||
| asyncio_run(conn.execute(delete(bounded_service._cache_table))) | ||
| for output_column in bounded_service.binding.output_columns: | ||
| asyncio_run(conn.execute(delete(bounded_service._tables[output_column.split('.')[0]]._table))) |
There was a problem hiding this comment.
The output tables may be same. Can you add them into a set and then delete them?
tests/tests_caching_logic.py
Outdated
| for index, (query_type, aidb_query, exact_query) in enumerate(queries): | ||
| # Run the query on the aidb database | ||
| logger.info(f'Running query {exact_query} in ground truth database') | ||
| # Run the query on the ground truth database |
There was a problem hiding this comment.
Write comments in the correct locations.
tests/tests_caching_logic.py
Outdated
| del aidb_engine | ||
| p.terminate() | ||
| p.join() | ||
| time.sleep(1) |
There was a problem hiding this comment.
I believe the join() is necessary or the server startup for the second test has some problems: https://github.com/ddkang/aidb/actions/runs/9025134318/job/24800303051. The sleep() is redundant and I have removed that.
* Fix how the service to clear cache are collected * Reduce redundant table deletion * Comment Fix * Remove redundant sleep
* Use the correct graph to collect service
|
@ttt-77 Could you please review this? |
tests/tests_caching_logic.py
Outdated
|
|
||
| asyncio_run(aidb_engine.clear_ml_cache(["lights01"])) | ||
|
|
||
| for index, (query_type, aidb_query, exact_query) in enumerate(queries): |
There was a problem hiding this comment.
Refactor the code. Could this loop be merged into previous one?
aidb/engine/engine.py
Outdated
| service_name_list = set(service_name_list) | ||
|
|
||
| # Get all the services that need to be cleared because of foreign key constraints | ||
| inference_graph = self._config.inference_graph |
There was a problem hiding this comment.
The edge in inference_graph doesn't represent two nodes have foreign key constraints
|
I've reconsidered the clearing logic. Now I'm planning to use the following procedure:
Are there any problems with this procedure? Or can it be simplified in some way? |
|
Looks good. |
* Merge the two stage of testing using a loop * Refactor the cache clearing using the table graph
|
@ttt-77 Could you please check this? The clearing steps are more complicated than I thought but I think all the steps are necessary. |
Added a function to delete all the data in the cache table. Trying to resolve issue #122.