Skip to content

fix: NebulaGraph backend - enable concurrent operations and fix datet…#1314

Merged
sscargal merged 2 commits intoMemMachine:mainfrom
wenhaocs:haowen/fix_test
Apr 10, 2026
Merged

fix: NebulaGraph backend - enable concurrent operations and fix datet…#1314
sscargal merged 2 commits intoMemMachine:mainfrom
wenhaocs:haowen/fix_test

Conversation

@wenhaocs
Copy link
Copy Markdown
Contributor

@wenhaocs wenhaocs commented Apr 8, 2026

Purpose of the change

Fix some issues when using NebulaGraph as backend.

Description

  1. The client SDK was using a single session. Now change to use a session pool so current requests can be handled.
  2. Fix to use timezone date time.
  3. Fix filters.

Fixes/Closes

Fixes #(issue number)

Type of change

[Please delete options that are not relevant.]

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (does not change functionality, e.g., code style improvements, linting)
  • Documentation update
  • Project Maintenance (updates to build scripts, CI, etc., that do not affect the main project)
  • Security (improves security without changing functionality)

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration.

[Please delete options that are not relevant.]

  • Unit Test
  • Integration Test
  • End-to-end Test
  • Test Script (please provide)
  • Manual verification (list step-by-step instructions)

Test Results: [Attach logs, screenshots, or relevant output]

Checklist

[Please delete options that are not relevant.]

  • I have signed the commit(s) within this pull request
  • My code follows the style guidelines of this project (See STYLE_GUIDE.md)
  • I have performed a self-review of my own code
  • I have commented my code
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added unit tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules
  • I have checked my code and corrected any misspellings

Maintainer Checklist

  • Confirmed all checks passed
  • Contributor has signed the commit(s)
  • Reviewed the code
  • Run, Tested, and Verified the change(s) work as expected

Screenshots/Gifs

[If applicable, add screenshots or GIFs that show the changes in action. This is especially helpful for API responses. Otherwise, delete this section or type "N/A".]

Further comments

[Add any other relevant information here, such as potential side effects, future considerations, or any specific questions for the reviewer. Otherwise, type "None".]

wenhaocs added 2 commits April 8, 2026 15:27
…ime/filter issues

Signed-off-by: wenhaocs <19355821+wenhaocs@users.noreply.github.com>
Signed-off-by: wenhaocs <19355821+wenhaocs@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes NebulaGraph backend issues by improving concurrency handling, timezone-aware datetime support, and filter expressiveness.

Changes:

  • Switch NebulaGraph test client setup to use a session pool (while keeping a temporary bootstrap session for schema/graph initialization).
  • Update NebulaGraph GQL type/value formatting to use zoned datetimes and handle NULL properties from schema evolution.
  • Extend NebulaGraph filter rendering to support IN and NOT, and hash long embedding metric companion property names to avoid identifier length limits.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
packages/server/src/memmachine_server/common/vector_graph_store/nebula_graph_vector_graph_store.py Adds zoned datetime formatting/type inference, IN/NOT filter rendering, NULL-property skipping, and hashed metric companion names.
packages/server/server_tests/memmachine_server/episodic_memory/conftest.py Updates NebulaGraph async client fixture to initialize schema/graph with a temporary client and then reconnect using a session pool.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

else:
# Default to UTC
params[param_name] = value.strftime("%Y-%m-%dT%H:%M:%S.%f +00:00")
return f'zoned_datetime({placeholder}, "%Y-%m-%dT%H:%M:%S %Ez")'
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Datetime cursor parameters are formatted with microseconds (".%f") but the zoned_datetime() format string passed is "%Y-%m-%dT%H:%M:%S %Ez" (no .%f). This mismatch will cause zoned_datetime() parsing to fail for tz-aware and naive datetimes. Make the formatted value and the format string consistent (either drop microseconds from the value, or include .%f in the format string, and ensure the timezone portion matches the chosen pattern).

Suggested change
return f'zoned_datetime({placeholder}, "%Y-%m-%dT%H:%M:%S %Ez")'
return f'zoned_datetime({placeholder}, "%Y-%m-%dT%H:%M:%S.%f %Ez")'

Copilot uses AI. Check for mistakes.
Comment on lines +1400 to +1403
return f'zoned_datetime("{formatted_str}", "%Y-%m-%dT%H:%M:%S %Ez")'
# No timezone info, default to UTC (+00:00)
formatted_str = value.strftime("%Y-%m-%dT%H:%M:%S.%f +00:00")
return f'zoned_datetime("{formatted_str}", "%Y-%m-%dT%H:%M:%S %Ez")'
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_format_value() builds datetime strings including microseconds (".%f") but passes the format string "%Y-%m-%dT%H:%M:%S %Ez" to zoned_datetime(), which does not include microseconds. This will likely break inserts/filters involving datetime values. Align the produced datetime literal with the format string (e.g., add .%f to the format or omit microseconds in the string).

Suggested change
return f'zoned_datetime("{formatted_str}", "%Y-%m-%dT%H:%M:%S %Ez")'
# No timezone info, default to UTC (+00:00)
formatted_str = value.strftime("%Y-%m-%dT%H:%M:%S.%f +00:00")
return f'zoned_datetime("{formatted_str}", "%Y-%m-%dT%H:%M:%S %Ez")'
return f'zoned_datetime("{formatted_str}", "%Y-%m-%dT%H:%M:%S.%f %Ez")'
# No timezone info, default to UTC (+00:00)
formatted_str = value.strftime("%Y-%m-%dT%H:%M:%S.%f +00:00")
return f'zoned_datetime("{formatted_str}", "%Y-%m-%dT%H:%M:%S.%f %Ez")'

Copilot uses AI. Check for mistakes.
Comment on lines 1433 to 1436
Returns:
Property name for the metric companion (e.g., "similarity_metric_for_vec")

"""
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring/example implies the metric companion property is always named like "similarity_metric_for_", but for long embedding names this function now returns a hashed "sim_metric_" value. Update the docstring to reflect the new behavior so callers/debugging aren’t misled.

Copilot uses AI. Check for mistakes.
Comment on lines +1558 to +1562
sanitized_prop = self._sanitize_name(prop_name)
prop_ref = f"{node_alias}.{sanitized_prop}"
value_strs = [self._format_value(v) for v in expr.values]
values_list = ", ".join(value_strs)
return f"{prop_ref} IN [{values_list}]"
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New FilterExpr support for the In node is added here, but the NebulaGraph store test suite currently exercises Comparison/IsNull/And/Or and not In. Add a unit/integration test that uses FilterIn (or parse_filter("field IN (...)")) against NebulaGraphVectorGraphStore to ensure the rendered query works end-to-end.

Copilot uses AI. Check for mistakes.
Comment on lines +1570 to +1572
if isinstance(expr, Not):
inner_clause = render(expr.expr)
return f"NOT ({inner_clause})"
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New FilterExpr support for Not is added here, but there’s no NebulaGraphVectorGraphStore test that validates NOT / NOT IN behavior end-to-end. Add a test that exercises FilterNot (e.g., parse_filter("NOT (...)"), or "field NOT IN (...)" which parses to Not(In(...))) to confirm the generated WHERE clause behaves correctly in NebulaGraph.

Copilot uses AI. Check for mistakes.
Comment on lines +62 to 66
# First connect without session pool to set up schema and graph
temp_client = await NebulaAsyncClient.connect(
hosts=connection_info["hosts"],
username=connection_info["username"],
password=connection_info["password"],
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

temp_client is created to bootstrap schema/graph, but if any of the setup executes raise, the fixture skips without closing temp_client (resource leak / dangling sessions). Wrap the schema setup in a try/finally (or context manager) to ensure temp_client.close() is always awaited before skipping/raising.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@sscargal sscargal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@sscargal sscargal merged commit af5a1a3 into MemMachine:main Apr 10, 2026
48 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants