Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
8a1f180
Bump unison dep to get new synhash stuff
ChrisPenner Aug 19, 2024
1f09c22
Start splitting off stuff into NamespaceDiffs2
ChrisPenner Aug 15, 2024
935cb35
Move Postgres PPED module into Share
ChrisPenner Aug 19, 2024
449e736
Implement Postgres names generator
ChrisPenner Aug 19, 2024
e9588f6
Bump unison dep
ChrisPenner Aug 19, 2024
bcc10a5
Compute typelookups
ChrisPenner Aug 19, 2024
f367af2
Add v1 version of getting names in project
ChrisPenner Aug 21, 2024
62f9947
Implement making libdeps
ChrisPenner Aug 21, 2024
fae54bd
WIP transitive deps
ChrisPenner Aug 21, 2024
442191f
bump unison
mitchellwrosen Dec 30, 2024
bcb7068
get code compiling with wundefineds
mitchellwrosen Jan 13, 2025
3e8aee7
sketch out 3-way namespace diff
mitchellwrosen Jan 21, 2025
6f9f603
move a couple helpers from Share.NamespaceDiffs to Share.NamespaceDif…
mitchellwrosen Jan 21, 2025
6313e81
move combineTermsAndTypes from Share.NamespaceDiffs to Share.Namespac…
mitchellwrosen Jan 21, 2025
b331c9f
move compressNameTree from Share.NamespaceDiffs to Share.NamespaceDif…
mitchellwrosen Jan 21, 2025
8b2b877
continue processing namespace diff
mitchellwrosen Jan 21, 2025
27eeb4e
Return propagated updates in diff payload
mitchellwrosen Jan 27, 2025
86f2573
switch over to three-way namespace diffs in `diffCausals`
mitchellwrosen Jan 30, 2025
30dc66e
delete old two-way diff stuff and consolidate modules again
mitchellwrosen Jan 30, 2025
e070923
pass through (but ignore) libdeps diffs in diffCausals
mitchellwrosen Feb 3, 2025
def99ff
add libdeps diff to the json blob
mitchellwrosen Feb 4, 2025
a231016
⅄ main → share-3waydiff
mitchellwrosen Feb 5, 2025
c3eeac1
omit constructors from term diff, rename/rekey namespace_diffs table
mitchellwrosen Feb 12, 2025
0791861
⅄ main → share-3waydiff
mitchellwrosen Feb 12, 2025
3f98db4
⅄ main → share-3waydiff
mitchellwrosen Feb 24, 2025
d2e5038
delete accidentally-created Postgres.hs file
mitchellwrosen Feb 24, 2025
7821ef5
re-run transcripts
mitchellwrosen Feb 24, 2025
b931f3e
⅄ main → share-3waydiff
mitchellwrosen Mar 3, 2025
56c8332
bump unison dep
mitchellwrosen Mar 17, 2025
53df207
⅄ bump-unison-dep → share-3waydiff
mitchellwrosen Mar 18, 2025
421da83
include propagated updates in diff payload
mitchellwrosen Mar 18, 2025
86a397d
properly filter out parts of a diff that contain only constructors
mitchellwrosen Mar 20, 2025
5466a91
⅄ main → share-3waydiff
mitchellwrosen Mar 27, 2025
262077d
fix namespace diff from-branch
mitchellwrosen Mar 31, 2025
a513698
include propagated updates in namespace diff
mitchellwrosen Mar 31, 2025
24dd624
bump to ucm-0.5.37 in ci
mitchellwrosen Mar 31, 2025
81dc256
re-run transcripts with ucm 0.5.37
mitchellwrosen Mar 31, 2025
fc7c912
⅄ main → share-3waydiff
mitchellwrosen Mar 31, 2025
d887e00
use Compose instead of MaybeT
mitchellwrosen Mar 31, 2025
a4edbc4
re-enable contribution diffs background worker
mitchellwrosen Apr 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ dependencies:
- share-auth
- unison-hashing-v2
- unison-codebase-sqlite-hashing-v2
- unison-merge
- unison-parser-typechecker
- unison-prelude
- unison-pretty-printer
Expand Down
5 changes: 4 additions & 1 deletion share-api.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ library
Share.IDs
Share.Metrics
Share.Monitoring
Share.Names.Postgres
Share.NamespaceDiffs
Share.Postgres
Share.Postgres.Admin
Expand Down Expand Up @@ -85,6 +86,7 @@ library
Share.Postgres.Users.Queries
Share.Prelude
Share.Prelude.Orphans
Share.PrettyPrintEnvDecl.Postgres
Share.Project
Share.Redis
Share.Release
Expand Down Expand Up @@ -170,7 +172,6 @@ library
Share.Web.UCM.SyncV2.Impl
Share.Web.UCM.SyncV2.Queries
Share.Web.UCM.SyncV2.Types
Unison.PrettyPrintEnvDecl.Postgres
Unison.Server.NameSearch.Postgres
Unison.Server.Share.Definitions
Unison.Server.Share.DefinitionSummary
Expand Down Expand Up @@ -295,6 +296,7 @@ library
, unison-core1
, unison-hash
, unison-hashing-v2
, unison-merge
, unison-parser-typechecker
, unison-prelude
, unison-pretty-printer
Expand Down Expand Up @@ -445,6 +447,7 @@ executable share-api
, unison-core1
, unison-hash
, unison-hashing-v2
, unison-merge
, unison-parser-typechecker
, unison-prelude
, unison-pretty-printer
Expand Down
17 changes: 17 additions & 0 deletions sql/2025-02-12_namespace_diff_key.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-- Recreate namespace diffs table, since we're changing a foreign key reference
-- Could truncate and alter columns instead, but it's more work

DROP TABLE namespace_diffs;

CREATE TABLE namespace_diffs (
left_causal_id INTEGER NOT NULL REFERENCES causals(id) ON DELETE CASCADE,
right_causal_id INTEGER NOT NULL REFERENCES causals(id) ON DELETE CASCADE,

-- Since different codebases can have different variable names and such we also need to sandbox diffs by codebase owner
left_codebase_owner_user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
right_codebase_owner_user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,

diff JSONB NOT NULL,

PRIMARY KEY (left_causal_id, right_causal_id, left_codebase_owner_user_id, right_codebase_owner_user_id)
);
3 changes: 2 additions & 1 deletion src/Share/BackgroundJobs.hs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
module Share.BackgroundJobs (startWorkers) where

import Ki.Unlifted qualified as Ki
import Share.BackgroundJobs.Diffs.ContributionDiffs qualified as ContributionDiffs
import Share.BackgroundJobs.Monad (Background)
import Share.BackgroundJobs.Search.DefinitionSync qualified as DefnSearch

-- | Kicks off all background workers.
startWorkers :: Ki.Scope -> Background ()
startWorkers scope = do
DefnSearch.worker scope
ContributionDiffs.worker scope

-- Temporary disable background diff jobs until the new diffing logic is done.
-- ContributionDiffs.worker scope
-- SerializedEntitiesMigration.worker scope
9 changes: 5 additions & 4 deletions src/Share/BackgroundJobs/Diffs/ContributionDiffs.hs
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,18 @@ processDiffs authZReceipt = Metrics.recordContributionDiffDuration . runExceptT

diffContribution :: AuthZ.AuthZReceipt -> ContributionId -> ExceptT NamespaceDiffError Background ()
diffContribution authZReceipt contributionId = do
( project,
( bestCommonAncestorCausalId,
project,
newBranch@Branch {causal = newBranchCausalId},
oldBranch@Branch {causal = oldBranchCausalId}
) <- ExceptT $ PG.tryRunTransaction $ do
Contribution {sourceBranchId = newBranchId, targetBranchId = oldBranchId, projectId} <- ContributionsQ.contributionById contributionId `whenNothingM` throwError (MissingEntityError $ EntityMissing (ErrorID "contribution:missing") "Contribution not found")
Contribution {bestCommonAncestorCausalId, sourceBranchId = newBranchId, targetBranchId = oldBranchId, projectId} <- ContributionsQ.contributionById contributionId `whenNothingM` throwError (MissingEntityError $ EntityMissing (ErrorID "contribution:missing") "Contribution not found")
project <- Q.projectById projectId `whenNothingM` throwError (MissingEntityError $ EntityMissing (ErrorID "project:missing") "Project not found")
newBranch <- Q.branchById newBranchId `whenNothingM` throwError (MissingEntityError $ EntityMissing (ErrorID "branch:missing") "Source branch not found")
oldBranch <- Q.branchById oldBranchId `whenNothingM` throwError (MissingEntityError $ EntityMissing (ErrorID "branch:missing") "Target branch not found")
pure (project, newBranch, oldBranch)
pure (bestCommonAncestorCausalId, project, newBranch, oldBranch)
let oldCodebase = Codebase.codebaseForProjectBranch authZReceipt project oldBranch
let newCodebase = Codebase.codebaseForProjectBranch authZReceipt project newBranch
-- This method saves the diff so it'll be there when we need it, so we don't need to do anything with it.
_ <- Diffs.diffCausals authZReceipt (oldCodebase, oldBranchCausalId) (newCodebase, newBranchCausalId)
_ <- Diffs.diffCausals authZReceipt (oldCodebase, oldBranchCausalId) (newCodebase, newBranchCausalId) bestCommonAncestorCausalId
pure ()
6 changes: 3 additions & 3 deletions src/Share/BackgroundJobs/Search/DefinitionSync.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import Share.Postgres.Queries qualified as PG
import Share.Postgres.Releases.Queries qualified as RQ
import Share.Postgres.Search.DefinitionSearch.Queries qualified as DDQ
import Share.Prelude
import Share.PrettyPrintEnvDecl.Postgres qualified as PPEPostgres
import Share.Project (Project (..))
import Share.Release (Release (..))
import Share.Utils.Logging qualified as Logging
Expand All @@ -52,7 +53,6 @@ import Unison.Name qualified as Name
import Unison.NameSegment (libSegment)
import Unison.PrettyPrintEnv qualified as PPE
import Unison.PrettyPrintEnvDecl qualified as PPED
import Unison.PrettyPrintEnvDecl.Postgres qualified as PPEPostgres
import Unison.Reference (TypeReference)
import Unison.Reference qualified as Reference
import Unison.Server.Share.DefinitionSummary qualified as Summary
Expand Down Expand Up @@ -124,10 +124,10 @@ syncRelease authZReceipt releaseId = fmap (fromMaybe []) . runMaybeT $ do
let codebaseLoc = Codebase.codebaseLocationForProjectRelease ownerUserId
let codebase = Codebase.codebaseEnv authZReceipt codebaseLoc
Codebase.codebaseMToTransaction codebase $ do
termsCursor <- lift $ NLOps.termsWithinNamespace nlReceipt bhId
termsCursor <- lift $ NLOps.projectTermsWithinRoot nlReceipt bhId

termErrs <- syncTerms namesPerspective bhId projectId releaseId termsCursor
typesCursor <- lift $ NLOps.typesWithinNamespace nlReceipt bhId
typesCursor <- lift $ NLOps.projectTypesWithinRoot nlReceipt bhId
typeErrs <- syncTypes namesPerspective projectId releaseId typesCursor
pure (termErrs <> typeErrs)

Expand Down
1 change: 1 addition & 0 deletions src/Share/Codebase.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ module Share.Codebase
expectTypeOfTerms,
expectTypeOfReferent,
expectTypeOfReferents,
expectTypeOfConstructor,
loadTypeOfConstructor,
loadTypeOfReferent,
loadTypeDeclaration,
Expand Down
38 changes: 38 additions & 0 deletions src/Share/Names/Postgres.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
-- | Efficiently fetch a Names object for a given set of labeled dependencies.
module Share.Names.Postgres (namesForReferences) where

import Control.Lens
import Data.Set qualified as Set
import Share.Postgres qualified as PG
import Share.Postgres.NameLookups.Conversions qualified as CV
import Share.Postgres.NameLookups.Ops qualified as NameLookupOps
import Share.Postgres.NameLookups.Types (NamesPerspective)
import Share.Postgres.NameLookups.Types qualified as NameLookups
import Share.Postgres.Refs.Types
import Share.Prelude
import Unison.LabeledDependency (LabeledDependency)
import Unison.Name (Name)
import Unison.Names (Names)
import Unison.Names qualified as Names
import Unison.Reference qualified as V1
import Unison.Referent qualified as V1

namesForReferences :: forall m. (PG.QueryM m) => NamesPerspective -> Set LabeledDependency -> m Names
namesForReferences namesPerspective refs = do
withPGRefs <-
Set.toList refs
& CV.labeledDependencies1ToPG
(termNames, typeNames) <- foldMapM namesForReference withPGRefs
pure $ Names.fromTermsAndTypes termNames typeNames
where
-- TODO: Can probably speed this up by skipping suffixification.
Copy link
Member

Choose a reason for hiding this comment

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

Probably worth testing one of the common queries on prod with and without suffixification to see if the real-world cost changes :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, how might we go about doing this? (Btw, this was one of the functions you authored before I took over)

Copy link
Member

@ChrisPenner ChrisPenner Mar 3, 2025

Choose a reason for hiding this comment

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

It's a little leg-work to do it, sorry >_>

The queries it's running are here: https://github.com/unisoncomputing/share-api/blob/main/src/Share/Postgres/NameLookups/Queries.hs#L44-L122

You'll need to copy-paste that, then manually fill in the parameters into the query which is a little annoying tbh; you can probably query a release or something from the debug_project_releases view, then cross reference that with scoped_term_name_lookup to get the params you need;

From there you can EXPLAIN ... and/or EXPLAIN ANALYSE on the queries with and without the suffixification.

If you need DB credentials you can get a read-only login for psql via vault read secret/production/enlil/userdb-readonly; For some reason our main DB is still called users 🤷🏼

Or my preferred method:

pgprod_ro () {
        pg_secret=$(vault read /secret/production/enlil/userdb-readonly -format=json | jq .data)
        PGPASSWORD="$(echo "$pg_secret" | jq -r .password)" psql --username "$(echo "$pg_secret"  | jq -r .username)" --host "$(echo "$pg_secret"  | jq -r .hostname)" --port "$(echo "$pg_secret"  | jq -r .port)" -d users "$@"
}

Copy link
Member

@ChrisPenner ChrisPenner Mar 3, 2025

Choose a reason for hiding this comment

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

If you need a hand knowing where to poke around don't hesitate to ask, it's probably good to get more folks used to digging around :)

namesForReference :: Either (V1.Referent, PGReferent) (V1.Reference, PGReference) -> m ([(Name, V1.Referent)], [(Name, V1.Reference)])
namesForReference = \case
Left (ref, pgref) -> do
termNames <- fmap (bothMap NameLookups.reversedNameToName) <$> NameLookupOps.termNamesForRefWithinNamespace namesPerspective pgref Nothing
let termNames' = termNames <&> \(fqn, _suffixed) -> (fqn, ref)
pure $ (termNames', [])
Right (ref, pgref) -> do
typeNames <- fmap (bothMap NameLookups.reversedNameToName) <$> NameLookupOps.typeNamesForRefWithinNamespace namesPerspective pgref Nothing
let typeNames' = typeNames <&> \(fqn, _suffixed) -> (fqn, ref)
pure $ ([], typeNames')
Loading
Loading