diff options
author | Lester Solbakken <lester.solbakken@gmail.com> | 2024-04-04 11:10:19 +0200 |
---|---|---|
committer | Lester Solbakken <lester.solbakken@gmail.com> | 2024-04-04 11:10:19 +0200 |
commit | 5909a99d539e9b54df2643f9fe11d0b2726b18f8 (patch) | |
tree | e57dd61bc57952a1c7af204d7e39b9ce04d68a46 | |
parent | d383656b547d5075c5c052d6ebe9a31178d1060f (diff) | |
parent | e380bdd2a1b0eb6d2fea79ffde6ae1d5b7377857 (diff) |
Merge branch 'master' into lesters/update-platform-bundles-for-rag-2
49 files changed, 781 insertions, 324 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f077dd87b9d..ab79c607cab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -120,6 +120,7 @@ add_subdirectory(container-core) add_subdirectory(container-disc) add_subdirectory(container-messagebus) add_subdirectory(container-onnxruntime) +add_subdirectory(container-llama) add_subdirectory(container-search) add_subdirectory(container-search-and-docproc) add_subdirectory(container-spifly) diff --git a/Gemfile.lock b/Gemfile.lock index e7b22dd38be..e5f55aef8d0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -90,7 +90,7 @@ GEM public_suffix (5.0.4) racc (1.7.3) rainbow (3.1.1) - rake (13.1.0) + rake (13.2.0) rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) diff --git a/client/go/internal/cli/cmd/query.go b/client/go/internal/cli/cmd/query.go index 879c19c78a7..db6dfa0a158 100644 --- a/client/go/internal/cli/cmd/query.go +++ b/client/go/internal/cli/cmd/query.go @@ -175,9 +175,7 @@ func printResponseBody(body io.Reader, options printOptions, cli *CLI) error { return err } if event.Name == "token" { - if writingLine { - fmt.Fprint(cli.Stdout, " ") - } else { + if !writingLine { writingLine = true } var token struct { diff --git a/client/go/internal/cli/cmd/query_test.go b/client/go/internal/cli/cmd/query_test.go index af0ae1763e9..f5b113b6acb 100644 --- a/client/go/internal/cli/cmd/query_test.go +++ b/client/go/internal/cli/cmd/query_test.go @@ -10,7 +10,6 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/vespa-engine/vespa/client/go/internal/mock" ) @@ -106,10 +105,10 @@ event: token data: {"token": "The"} event: token -data: {"token": "Manhattan"} +data: {"token": " Manhattan"} event: token -data: {"token": "Project"} +data: {"token": " Project"} event: end ` @@ -121,7 +120,7 @@ event: token data: {"token": "The"} event: token -data: Manhattan +data: Manhattan event: error data: {"message": "something went wrong"} @@ -177,8 +176,7 @@ func assertQuery(t *testing.T, expectedQuery string, query ...string) { "{\n \"query\": \"result\"\n}\n", stdout.String(), "query output") - queryURL, err := queryServiceURL(client) - require.Nil(t, err) + queryURL := "http://127.0.0.1:8080" assert.Equal(t, queryURL+"/search/"+expectedQuery, client.LastRequest.URL.String()) } @@ -205,7 +203,3 @@ func assertQueryServiceError(t *testing.T, status int, errorMessage string) { stderr.String(), "error output") } - -func queryServiceURL(client *mock.HTTPClient) (string, error) { - return "http://127.0.0.1:8080", nil -} diff --git a/client/js/app/yarn.lock b/client/js/app/yarn.lock index 28313d7fb65..8993f580fd4 100644 --- a/client/js/app/yarn.lock +++ b/client/js/app/yarn.lock @@ -830,31 +830,31 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.1.4.tgz#19654d1026cc410975d46445180e70a5089b3e7d" integrity sha512-qprfWkn82Iw821mcKofJ5Pk9wgioHicxcQMxx+5zt5GSKoqdWvgG5AxVmpmUUjzTLPVSH5auBrhI93Deayn/DA== -"@fortawesome/fontawesome-common-types@6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.1.tgz#fdb1ec4952b689f5f7aa0bffe46180bb35490032" - integrity sha512-GkWzv+L6d2bI5f/Vk6ikJ9xtl7dfXtoRu3YGE6nq0p/FFqA1ebMOAWg3XgRyb0I6LYyYkiAo+3/KrwuBp8xG7A== +"@fortawesome/fontawesome-common-types@6.5.2": + version "6.5.2" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.2.tgz#eaf2f5699f73cef198454ebc0c414e3688898179" + integrity sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw== "@fortawesome/fontawesome-svg-core@^6": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.1.tgz#9d56d46bddad78a7ebb2043a97957039fcebcf0a" - integrity sha512-MfRCYlQPXoLlpem+egxjfkEuP9UQswTrlCOsknus/NcMoblTH2g0jPrapbcIb04KGA7E2GZxbAccGZfWoYgsrQ== + version "6.5.2" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.2.tgz#4b42de71e196039b0d5ccf88559b8044e3296c21" + integrity sha512-5CdaCBGl8Rh9ohNdxeeTMxIj8oc3KNBgIeLMvJosBMdslK/UnEB8rzyDRrbKdL1kDweqBPo4GT9wvnakHWucZw== dependencies: - "@fortawesome/fontawesome-common-types" "6.5.1" + "@fortawesome/fontawesome-common-types" "6.5.2" "@fortawesome/free-regular-svg-icons@^6": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.1.tgz#c98a91d2c9137ed54a7aa2362a916f46503e0627" - integrity sha512-m6ShXn+wvqEU69wSP84coxLbNl7sGVZb+Ca+XZq6k30SzuP3X4TfPqtycgUh9ASwlNh5OfQCd8pDIWxl+O+LlQ== + version "6.5.2" + resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.2.tgz#e8e04b4368d49920abdf1bacc63c67c870635222" + integrity sha512-iabw/f5f8Uy2nTRtJ13XZTS1O5+t+anvlamJ3zJGLEVE2pKsAWhPv2lq01uQlfgCX7VaveT3EVs515cCN9jRbw== dependencies: - "@fortawesome/fontawesome-common-types" "6.5.1" + "@fortawesome/fontawesome-common-types" "6.5.2" "@fortawesome/free-solid-svg-icons@^6": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.1.tgz#737b8d787debe88b400ab7528f47be333031274a" - integrity sha512-S1PPfU3mIJa59biTtXJz1oI0+KAXW6bkAb31XKhxdxtuXDiUIFsih4JR1v5BbxY7hVHsD1RKq+jRkVRaf773NQ== + version "6.5.2" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.2.tgz#9b40b077b27400a5e9fcbf2d15b986c7be69e9ca" + integrity sha512-QWFZYXFE7O1Gr1dTIp+D6UcFUF0qElOnZptpi7PBUMylJh+vFmIedVe1Ir6RM1t2tEQLLSV1k7bR4o92M+uqlw== dependencies: - "@fortawesome/fontawesome-common-types" "6.5.1" + "@fortawesome/fontawesome-common-types" "6.5.2" "@fortawesome/react-fontawesome@^0": version "0.2.0" @@ -1320,80 +1320,80 @@ resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.15.3.tgz#d2509048d69dbb72d5389a14945339f1430b2d3c" integrity sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w== -"@rollup/rollup-android-arm-eabi@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.2.tgz#fbf098f49d96a8cac9056f22f5fd80906ef3af85" - integrity sha512-3XFIDKWMFZrMnao1mJhnOT1h2g0169Os848NhhmGweEcfJ4rCi+3yMCOLG4zA61rbJdkcrM/DjVZm9Hg5p5w7g== - -"@rollup/rollup-android-arm64@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.2.tgz#0d2448251040fce19a98eee505dff5b3c8ec9b98" - integrity sha512-GdxxXbAuM7Y/YQM9/TwwP+L0omeE/lJAR1J+olu36c3LqqZEBdsIWeQ91KBe6nxwOnb06Xh7JS2U5ooWU5/LgQ== - -"@rollup/rollup-darwin-arm64@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.2.tgz#78db4d4da5b1b84c22adbe25c8a4961b3f22d3af" - integrity sha512-mCMlpzlBgOTdaFs83I4XRr8wNPveJiJX1RLfv4hggyIVhfB5mJfN4P8Z6yKh+oE4Luz+qq1P3kVdWrCKcMYrrA== - -"@rollup/rollup-darwin-x64@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.2.tgz#fcc05af54379f8ee5c7e954987d4514c6fd0fb42" - integrity sha512-yUoEvnH0FBef/NbB1u6d3HNGyruAKnN74LrPAfDQL3O32e3k3OSfLrPgSJmgb3PJrBZWfPyt6m4ZhAFa2nZp2A== - -"@rollup/rollup-linux-arm-gnueabihf@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.2.tgz#2ce200efa1ef4a56ee2af7b453edc74a259d7d31" - integrity sha512-GYbLs5ErswU/Xs7aGXqzc3RrdEjKdmoCrgzhJWyFL0r5fL3qd1NPcDKDowDnmcoSiGJeU68/Vy+OMUluRxPiLQ== - -"@rollup/rollup-linux-arm64-gnu@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.2.tgz#5a24aac882bff9abfda3f45f6f1db2166c342a4a" - integrity sha512-L1+D8/wqGnKQIlh4Zre9i4R4b4noxzH5DDciyahX4oOz62CphY7WDWqJoQ66zNR4oScLNOqQJfNSIAe/6TPUmQ== - -"@rollup/rollup-linux-arm64-musl@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.2.tgz#f1fb4c6f961d3f3397231a99e621d199200e4ea9" - integrity sha512-tK5eoKFkXdz6vjfkSTCupUzCo40xueTOiOO6PeEIadlNBkadH1wNOH8ILCPIl8by/Gmb5AGAeQOFeLev7iZDOA== - -"@rollup/rollup-linux-powerpc64le-gnu@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.13.2.tgz#46b2463d94ac3af3e0f7a2947b695397bc13b755" - integrity sha512-zvXvAUGGEYi6tYhcDmb9wlOckVbuD+7z3mzInCSTACJ4DQrdSLPNUeDIcAQW39M3q6PDquqLWu7pnO39uSMRzQ== - -"@rollup/rollup-linux-riscv64-gnu@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.2.tgz#47b932ee59a5395a3a341b0493e361d9e6032cf2" - integrity sha512-C3GSKvMtdudHCN5HdmAMSRYR2kkhgdOfye4w0xzyii7lebVr4riCgmM6lRiSCnJn2w1Xz7ZZzHKuLrjx5620kw== - -"@rollup/rollup-linux-s390x-gnu@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.13.2.tgz#8e14a1b3c3b9a4440c70a9c1ba12d32aa21f9712" - integrity sha512-l4U0KDFwzD36j7HdfJ5/TveEQ1fUTjFFQP5qIt9gBqBgu1G8/kCaq5Ok05kd5TG9F8Lltf3MoYsUMw3rNlJ0Yg== - -"@rollup/rollup-linux-x64-gnu@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.2.tgz#270e939194b66df77bcb33dd9a5ddf7784bd7997" - integrity sha512-xXMLUAMzrtsvh3cZ448vbXqlUa7ZL8z0MwHp63K2IIID2+DeP5iWIT6g1SN7hg1VxPzqx0xZdiDM9l4n9LRU1A== - -"@rollup/rollup-linux-x64-musl@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.2.tgz#e8dd0f3c2046acbda2934490b36552e856a3bc6a" - integrity sha512-M/JYAWickafUijWPai4ehrjzVPKRCyDb1SLuO+ZyPfoXgeCEAlgPkNXewFZx0zcnoIe3ay4UjXIMdXQXOZXWqA== - -"@rollup/rollup-win32-arm64-msvc@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.2.tgz#f8b65a4a7e7a6b383e7b14439129b2f474ff123c" - integrity sha512-2YWwoVg9KRkIKaXSh0mz3NmfurpmYoBBTAXA9qt7VXk0Xy12PoOP40EFuau+ajgALbbhi4uTj3tSG3tVseCjuA== - -"@rollup/rollup-win32-ia32-msvc@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.2.tgz#bc1c5a4fbc4337d6cb15da80a4de95fd53ab3573" - integrity sha512-2FSsE9aQ6OWD20E498NYKEQLneShWes0NGMPQwxWOdws35qQXH+FplabOSP5zEe1pVjurSDOGEVCE2agFwSEsw== - -"@rollup/rollup-win32-x64-msvc@4.13.2": - version "4.13.2" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.2.tgz#851959c4c1c3c6647aba1f388198c8243aed6917" - integrity sha512-7h7J2nokcdPePdKykd8wtc8QqqkqxIrUz7MHj6aNr8waBRU//NLDVnNjQnqQO6fqtjrtCdftpbTuOKAyrAQETQ== +"@rollup/rollup-android-arm-eabi@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.0.tgz#57936f50d0335e2e7bfac496d209606fa516add4" + integrity sha512-jwXtxYbRt1V+CdQSy6Z+uZti7JF5irRKF8hlKfEnF/xJpcNGuuiZMBvuoYM+x9sr9iWGnzrlM0+9hvQ1kgkf1w== + +"@rollup/rollup-android-arm64@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.0.tgz#81bba83b37382a2d0e30ceced06c8d3d85138054" + integrity sha512-fI9nduZhCccjzlsA/OuAwtFGWocxA4gqXGTLvOyiF8d+8o0fZUeSztixkYjcGq1fGZY3Tkq4yRvHPFxU+jdZ9Q== + +"@rollup/rollup-darwin-arm64@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.0.tgz#a371bd723a5c4c4a33376da72abfc3938066842b" + integrity sha512-BcnSPRM76/cD2gQC+rQNGBN6GStBs2pl/FpweW8JYuz5J/IEa0Fr4AtrPv766DB/6b2MZ/AfSIOSGw3nEIP8SA== + +"@rollup/rollup-darwin-x64@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.0.tgz#8baf2fda277c9729125017c65651296282412886" + integrity sha512-LDyFB9GRolGN7XI6955aFeI3wCdCUszFWumWU0deHA8VpR3nWRrjG6GtGjBrQxQKFevnUTHKCfPR4IvrW3kCgQ== + +"@rollup/rollup-linux-arm-gnueabihf@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.0.tgz#822830a8f7388d5b81d04c69415408d3bab1079b" + integrity sha512-ygrGVhQP47mRh0AAD0zl6QqCbNsf0eTo+vgwkY6LunBcg0f2Jv365GXlDUECIyoXp1kKwL5WW6rsO429DBY/bA== + +"@rollup/rollup-linux-arm64-gnu@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.0.tgz#e20fbe1bd4414c7119f9e0bba8ad17a6666c8365" + integrity sha512-x+uJ6MAYRlHGe9wi4HQjxpaKHPM3d3JjqqCkeC5gpnnI6OWovLdXTpfa8trjxPLnWKyBsSi5kne+146GAxFt4A== + +"@rollup/rollup-linux-arm64-musl@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.0.tgz#13f475596a62e1924f13fe1c8cf2c40e09a99b47" + integrity sha512-nrRw8ZTQKg6+Lttwqo6a2VxR9tOroa2m91XbdQ2sUUzHoedXlsyvY1fN4xWdqz8PKmf4orDwejxXHjh7YBGUCA== + +"@rollup/rollup-linux-powerpc64le-gnu@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.0.tgz#6a431c441420d1c510a205e08c6673355a0a2ea9" + integrity sha512-xV0d5jDb4aFu84XKr+lcUJ9y3qpIWhttO3Qev97z8DKLXR62LC3cXT/bMZXrjLF9X+P5oSmJTzAhqwUbY96PnA== + +"@rollup/rollup-linux-riscv64-gnu@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.0.tgz#53d9448962c3f9ed7a1672269655476ea2d67567" + integrity sha512-SDDhBQwZX6LPRoPYjAZWyL27LbcBo7WdBFWJi5PI9RPCzU8ijzkQn7tt8NXiXRiFMJCVpkuMkBf4OxSxVMizAw== + +"@rollup/rollup-linux-s390x-gnu@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.0.tgz#95f0c133b324da3e7e5c7d12855e0eb71d21a946" + integrity sha512-RxB/qez8zIDshNJDufYlTT0ZTVut5eCpAZ3bdXDU9yTxBzui3KhbGjROK2OYTTor7alM7XBhssgoO3CZ0XD3qA== + +"@rollup/rollup-linux-x64-gnu@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.0.tgz#820ada75c68ead1acc486e41238ca0d8f8531478" + integrity sha512-C6y6z2eCNCfhZxT9u+jAM2Fup89ZjiG5pIzZIDycs1IwESviLxwkQcFRGLjnDrP+PT+v5i4YFvlcfAs+LnreXg== + +"@rollup/rollup-linux-x64-musl@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.0.tgz#ca74f22e125efbe94c1148d989ef93329b464443" + integrity sha512-i0QwbHYfnOMYsBEyjxcwGu5SMIi9sImDVjDg087hpzXqhBSosxkE7gyIYFHgfFl4mr7RrXksIBZ4DoLoP4FhJg== + +"@rollup/rollup-win32-arm64-msvc@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.0.tgz#269023332297051d037a9593dcba92c10fef726b" + integrity sha512-Fq52EYb0riNHLBTAcL0cun+rRwyZ10S9vKzhGKKgeD+XbwunszSY0rVMco5KbOsTlwovP2rTOkiII/fQ4ih/zQ== + +"@rollup/rollup-win32-ia32-msvc@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.0.tgz#d7701438daf964011fd7ca33e3f13f3ff5129e7b" + integrity sha512-e/PBHxPdJ00O9p5Ui43+vixSgVf4NlLsmV6QneGERJ3lnjIua/kim6PRFe3iDueT1rQcgSkYP8ZBBXa/h4iPvw== + +"@rollup/rollup-win32-x64-msvc@4.14.0": + version "4.14.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.0.tgz#0bb7ac3cd1c3292db1f39afdabfd03ccea3a3d34" + integrity sha512-aGg7iToJjdklmxlUlJh/PaPNa4PmqHfyRMLunbL3eaMO0gp656+q1zOKkpJ/CVe9CryJv6tAN1HDoR8cNGzkag== "@sinclair/typebox@^0.27.8": version "0.27.8" @@ -4900,27 +4900,27 @@ rimraf@^3.0.2: glob "^7.1.3" rollup@^4.13.0: - version "4.13.2" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.13.2.tgz#ac57d2dc48e8f5562f5a6daadb9caee590069262" - integrity sha512-MIlLgsdMprDBXC+4hsPgzWUasLO9CE4zOkj/u6j+Z6j5A4zRY+CtiXAdJyPtgCsc42g658Aeh1DlrdVEJhsL2g== + version "4.14.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.14.0.tgz#c3e2cd479f1b2358b65c1f810fa05b51603d7be8" + integrity sha512-Qe7w62TyawbDzB4yt32R0+AbIo6m1/sqO7UPzFS8Z/ksL5mrfhA0v4CavfdmFav3D+ub4QeAgsGEe84DoWe/nQ== dependencies: "@types/estree" "1.0.5" optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.13.2" - "@rollup/rollup-android-arm64" "4.13.2" - "@rollup/rollup-darwin-arm64" "4.13.2" - "@rollup/rollup-darwin-x64" "4.13.2" - "@rollup/rollup-linux-arm-gnueabihf" "4.13.2" - "@rollup/rollup-linux-arm64-gnu" "4.13.2" - "@rollup/rollup-linux-arm64-musl" "4.13.2" - "@rollup/rollup-linux-powerpc64le-gnu" "4.13.2" - "@rollup/rollup-linux-riscv64-gnu" "4.13.2" - "@rollup/rollup-linux-s390x-gnu" "4.13.2" - "@rollup/rollup-linux-x64-gnu" "4.13.2" - "@rollup/rollup-linux-x64-musl" "4.13.2" - "@rollup/rollup-win32-arm64-msvc" "4.13.2" - "@rollup/rollup-win32-ia32-msvc" "4.13.2" - "@rollup/rollup-win32-x64-msvc" "4.13.2" + "@rollup/rollup-android-arm-eabi" "4.14.0" + "@rollup/rollup-android-arm64" "4.14.0" + "@rollup/rollup-darwin-arm64" "4.14.0" + "@rollup/rollup-darwin-x64" "4.14.0" + "@rollup/rollup-linux-arm-gnueabihf" "4.14.0" + "@rollup/rollup-linux-arm64-gnu" "4.14.0" + "@rollup/rollup-linux-arm64-musl" "4.14.0" + "@rollup/rollup-linux-powerpc64le-gnu" "4.14.0" + "@rollup/rollup-linux-riscv64-gnu" "4.14.0" + "@rollup/rollup-linux-s390x-gnu" "4.14.0" + "@rollup/rollup-linux-x64-gnu" "4.14.0" + "@rollup/rollup-linux-x64-musl" "4.14.0" + "@rollup/rollup-win32-arm64-msvc" "4.14.0" + "@rollup/rollup-win32-ia32-msvc" "4.14.0" + "@rollup/rollup-win32-x64-msvc" "4.14.0" fsevents "~2.3.2" rsvp@^4.8.4: @@ -5541,9 +5541,9 @@ v8-to-istanbul@^9.0.1: convert-source-map "^1.6.0" vite@^5.0.5: - version "5.2.7" - resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.7.tgz#e1b8a985eb54fcb9467d7f7f009d87485016df6e" - integrity sha512-k14PWOKLI6pMaSzAuGtT+Cf0YmIx12z9YGon39onaJNy8DLBfBJrzg9FQEmkAM5lpHBZs9wksWAsyF/HkpEwJA== + version "5.2.8" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.8.tgz#a99e09939f1a502992381395ce93efa40a2844aa" + integrity sha512-OyZR+c1CE8yeHw5V5t59aXsUPPVTHMDjEZz8MgguLL/Q7NblxhZUlTu9xSPqlsUO/y+X7dlU05jdhvyycD55DA== dependencies: esbuild "^0.20.1" postcss "^8.4.38" diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java index 93d65426b61..d877600db13 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java @@ -1,32 +1,31 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.model.builder.xml.dom; -import com.yahoo.config.provision.ClusterInfo; -import com.yahoo.config.provision.IntRange; import com.yahoo.collections.Pair; import com.yahoo.component.Version; import com.yahoo.config.application.api.DeployLogger; -import com.yahoo.config.provision.ZoneEndpoint; import com.yahoo.config.model.ConfigModelContext; import com.yahoo.config.provision.Capacity; import com.yahoo.config.provision.CloudAccount; +import com.yahoo.config.provision.ClusterInfo; import com.yahoo.config.provision.ClusterMembership; import com.yahoo.config.provision.ClusterResources; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.DockerImage; +import com.yahoo.config.provision.IntRange; import com.yahoo.config.provision.NodeResources; +import com.yahoo.config.provision.ZoneEndpoint; import com.yahoo.text.XML; import com.yahoo.vespa.model.HostResource; import com.yahoo.vespa.model.HostSystem; import com.yahoo.vespa.model.container.xml.ContainerModelBuilder; import org.w3c.dom.Element; import org.w3c.dom.Node; + import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.function.Function; import java.util.function.ToDoubleFunction; -import java.util.logging.Level; /** * A common utility class to represent a requirement for nodes during model building. @@ -77,8 +76,10 @@ public class NodesSpecification { Optional<CloudAccount> cloudAccount, boolean hasCountAttribute) { if (max.smallerThan(min)) - throw new IllegalArgumentException("Min resources must be larger or equal to max resources, but " + + throw new IllegalArgumentException("Max resources must be larger or equal to min resources, but " + max + " is smaller than " + min); + if (min.nodes() < 1) + throw new IllegalArgumentException("Min node count cannot be less than 1, but is " + min.nodes()); // Non-scaled resources must be equal if ( ! min.nodeResources().justNonNumbers().equals(max.nodeResources().justNonNumbers())) @@ -128,6 +129,9 @@ public class NodesSpecification { var groups = rangeFrom(nodesElement, "groups"); var groupSize = rangeFrom(nodesElement, "group-size"); + if (nodes.from().orElse(1) < 1) + throw new IllegalArgumentException("Min node resources cannot be less than 1, but is " + nodes.from().getAsInt()); + // Find the tightest possible limits for groups to avoid falsely concluding we are autoscaling // when only specifying group size int defaultMinGroups = nodes.from().orElse(1) / groupSize.to().orElse(nodes.from().orElse(1)); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java index 08b0398a98f..5f824950ecd 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java @@ -24,7 +24,6 @@ public class HostedSslConnectorFactory extends ConnectorFactory { private final SslClientAuth clientAuth; private final List<String> tlsCiphersOverride; private final boolean proxyProtocolEnabled; - private final boolean proxyProtocolMixedMode; private final Duration endpointConnectionTtl; private final List<String> remoteAddressHeaders; private final List<String> remotePortHeaders; @@ -37,7 +36,6 @@ public class HostedSslConnectorFactory extends ConnectorFactory { this.clientAuth = builder.clientAuth; this.tlsCiphersOverride = List.copyOf(builder.tlsCiphersOverride); this.proxyProtocolEnabled = builder.proxyProtocolEnabled; - this.proxyProtocolMixedMode = builder.proxyProtocolMixedMode; this.endpointConnectionTtl = builder.endpointConnectionTtl; this.remoteAddressHeaders = List.copyOf(builder.remoteAddressHeaders); this.remotePortHeaders = List.copyOf(builder.remotePortHeaders); @@ -70,7 +68,7 @@ public class HostedSslConnectorFactory extends ConnectorFactory { } connectorBuilder .proxyProtocol(new ConnectorConfig.ProxyProtocol.Builder() - .enabled(proxyProtocolEnabled).mixedMode(proxyProtocolMixedMode)) + .enabled(proxyProtocolEnabled)) .idleTimeout(Duration.ofSeconds(30).toSeconds()) .maxConnectionLife(endpointConnectionTtl != null ? endpointConnectionTtl.toSeconds() : 0) .accessLog(new ConnectorConfig.AccessLog.Builder() @@ -89,7 +87,6 @@ public class HostedSslConnectorFactory extends ConnectorFactory { SslClientAuth clientAuth; List<String> tlsCiphersOverride = List.of(); boolean proxyProtocolEnabled; - boolean proxyProtocolMixedMode; Duration endpointConnectionTtl; EndpointCertificateSecrets endpointCertificate; String tlsCaCertificatesPem; @@ -101,7 +98,7 @@ public class HostedSslConnectorFactory extends ConnectorFactory { public Builder clientAuth(SslClientAuth auth) { clientAuth = auth; return this; } public Builder endpointConnectionTtl(Duration ttl) { endpointConnectionTtl = ttl; return this; } public Builder tlsCiphersOverride(Collection<String> ciphers) { tlsCiphersOverride = List.copyOf(ciphers); return this; } - public Builder proxyProtocol(boolean enabled, boolean mixedMode) { proxyProtocolEnabled = enabled; proxyProtocolMixedMode = mixedMode; return this; } + public Builder proxyProtocol(boolean enabled) { proxyProtocolEnabled = enabled; return this; } public Builder endpointCertificate(EndpointCertificateSecrets cert) { this.endpointCertificate = cert; return this; } public Builder tlsCaCertificatesPath(String path) { this.tlsCaCertificatesPath = path; return this; } public Builder tlsCaCertificatesPem(String pem) { this.tlsCaCertificatesPem = pem; return this; } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java index c71dbb158b0..eac03531b86 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java @@ -598,7 +598,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { // If the deployment contains certificate/private key reference, setup TLS port var builder = HostedSslConnectorFactory.builder(serverName, getMtlsDataplanePort(state)) - .proxyProtocol(true, state.getProperties().featureFlags().enableProxyProtocolMixedMode()) + .proxyProtocol(state.zone().cloud().useProxyProtocol()) .tlsCiphersOverride(state.getProperties().tlsCiphersOverride()) .endpointConnectionTtl(state.getProperties().endpointConnectionTtl()); var endpointCert = state.endpointCertificateSecrets().orElse(null); @@ -657,7 +657,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { // Setup dedicated connector var connector = HostedSslConnectorFactory.builder(server.getComponentId().getName()+"-token", tokenPort) .tokenEndpoint(true) - .proxyProtocol(false, false) + .proxyProtocol(false) .endpointCertificate(endpointCert) .remoteAddressHeader("X-Forwarded-For") .remotePortHeader("X-Forwarded-Port") diff --git a/config-model/src/test/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecificationTest.java b/config-model/src/test/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecificationTest.java index a40d5f22939..344471cada0 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecificationTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecificationTest.java @@ -91,6 +91,8 @@ public class NodesSpecificationTest { () -> nodesSpecification("<nodes><resources memory='b' /></nodes>")); assertThrows(IllegalArgumentException.class, () -> nodesSpecification("<nodes><resources memory='Yb' /></nodes>")); + assertThrows(IllegalArgumentException.class, + () -> nodesSpecification("<nodes count='[0, 1]'></nodes>")); } @Test diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/Cloud.java b/config-provisioning/src/main/java/com/yahoo/config/provision/Cloud.java index 38705b02a28..463d9edcdad 100644 --- a/config-provisioning/src/main/java/com/yahoo/config/provision/Cloud.java +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/Cloud.java @@ -57,6 +57,11 @@ public class Cloud { return account; } + /** Returns whether load balancers use proxy protocol v1 or not (e.g. use source NAT). */ + public boolean useProxyProtocol() { + return !name.equals(CloudName.AZURE); + } + /** For testing purposes only */ public static Cloud defaultCloud() { return new Builder().build(); diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/Zone.java b/config-provisioning/src/main/java/com/yahoo/config/provision/Zone.java index 5ef42d12dc1..73c6010f514 100644 --- a/config-provisioning/src/main/java/com/yahoo/config/provision/Zone.java +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/Zone.java @@ -54,11 +54,6 @@ public class Zone { this.region = region; } - // TODO(mpolden): For compatibility with older config models. Remove when versions < 8.76 are gone - public Cloud getCloud() { - return cloud(); - } - /** Returns the current cloud */ public Cloud cloud() { return cloud; } @@ -102,5 +97,10 @@ public class Zone { return Objects.hash(environment, region); } + // TODO(mpolden): For compatibility with older config models. Remove when versions < 8.327 are gone + @Deprecated(forRemoval = true) + public Cloud getCloud() { + return cloud(); + } } diff --git a/configdefinitions/src/main/java/com/yahoo/search/significance/config/package-info.java b/configdefinitions/src/main/java/com/yahoo/search/significance/config/package-info.java new file mode 100644 index 00000000000..1093e194c87 --- /dev/null +++ b/configdefinitions/src/main/java/com/yahoo/search/significance/config/package-info.java @@ -0,0 +1,6 @@ +// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +@ExportPackage +package com.yahoo.search.significance.config; + +import com.yahoo.osgi.annotation.ExportPackage; + diff --git a/configdefinitions/src/vespa/CMakeLists.txt b/configdefinitions/src/vespa/CMakeLists.txt index 049475c9c1b..b80a7ac73e3 100644 --- a/configdefinitions/src/vespa/CMakeLists.txt +++ b/configdefinitions/src/vespa/CMakeLists.txt @@ -92,3 +92,5 @@ install_config_definition(col-bert-embedder.def embedding.col-bert-embedder.def) install_config_definition(splade-embedder.def embedding.splade-embedder.def) install_config_definition(cloud-data-plane-filter.def jdisc.http.filter.security.cloud.config.cloud-data-plane-filter.def) install_config_definition(cloud-token-data-plane-filter.def jdisc.http.filter.security.cloud.config.cloud-token-data-plane-filter.def) +install_config_definition(significance.def search.significance.config.significance.def) + diff --git a/configdefinitions/src/vespa/significance.def b/configdefinitions/src/vespa/significance.def new file mode 100644 index 00000000000..e0cc5b4c611 --- /dev/null +++ b/configdefinitions/src/vespa/significance.def @@ -0,0 +1,6 @@ +# Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +namespace=search.significance.config + +model[].language string +model[].path model + diff --git a/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java b/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java index c2f101d7784..ebd5c38e3a3 100644 --- a/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java +++ b/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java @@ -123,8 +123,10 @@ public class StateHandler extends AbstractRequestHandler implements CapabilityRe } private String resolveContentType(URI requestUri) { - if (resolvePath(requestUri).equals(HISTOGRAMS_PATH) || isPrometheusRequest(requestUri.getQuery())) { + if (resolvePath(requestUri).equals(HISTOGRAMS_PATH)) { return "text/plain; charset=utf-8"; + } else if (isPrometheusRequest(requestUri.getQuery())) { + return "text/plain; version=0.0.4"; } else { return "application/json"; } @@ -224,45 +226,38 @@ public class StateHandler extends AbstractRequestHandler implements CapabilityRe var timestamp = snapshot.getToTime(TimeUnit.MILLISECONDS); var builder = new StringBuilder(); builder.append("# NOTE: THIS API IS NOT INTENDED FOR PUBLIC USE\n"); + var metrics = new ArrayList<PrometheusEntry>(); + for (var tuple : collapseMetrics(snapshot, consumer)) { var dims = toPrometheusDimensions(tuple.dim); var metricName = prometheusSanitizedName(tuple.key) + "_"; if (tuple.val instanceof GaugeMetric gauge) { - appendPrometheusEntry(builder, metricName + "max", dims, gauge.getMax(), timestamp); - appendPrometheusEntry(builder, metricName + "sum", dims, gauge.getSum(), timestamp); - appendPrometheusEntry(builder, metricName + "count", dims, gauge.getCount(), timestamp); + metrics.add(new PrometheusEntry(metricName + "max", dims, gauge.getMax())); + metrics.add(new PrometheusEntry(metricName + "sum", dims, gauge.getSum())); + metrics.add(new PrometheusEntry(metricName + "count", dims, gauge.getCount())); if (gauge.getPercentiles().isPresent()) { for (Tuple2<String, Double> prefixAndValue : gauge.getPercentiles().get()) { - appendPrometheusEntry(builder, metricName + prefixAndValue.first + "percentile", dims, prefixAndValue.second, timestamp); + metrics.add(new PrometheusEntry(metricName + prefixAndValue.first + "percentile", dims, prefixAndValue.second)); } } } else if (tuple.val instanceof CountMetric count) { - appendPrometheusEntry(builder, metricName + "count", dims, count.getCount(), timestamp); + metrics.add(new PrometheusEntry(metricName + "count", dims, count.getCount())); } } + Collections.sort(metrics); + metrics.forEach(prometheusEntry -> prometheusEntry.appendPrometheusEntry(builder, timestamp)); return builder.toString().getBytes(UTF_8); } - private void appendPrometheusEntry(StringBuilder builder, String metricName, String dimension, Number value, long timeStamp) { - builder.append("# HELP ") - .append(metricName) - .append("\n# TYPE ") - .append(metricName) - .append(" untyped\n"); - - builder.append(metricName) - .append("{").append(dimension).append("}") - .append(" ").append(sanitizeIfDouble(value)).append(" ") - .append(timeStamp).append("\n"); - } - private String toPrometheusDimensions(MetricDimensions dimensions) { - if (dimensions == null) return ""; + if (dimensions == null || !dimensions.iterator().hasNext()) return ""; StringBuilder builder = new StringBuilder(); + builder.append("{"); dimensions.forEach(entry -> { - var sanitized = prometheusSanitizedName(entry.getKey()) + "=\"" + entry.getValue() + "\","; + var sanitized = prometheusSanitizedName(entry.getKey()) + "=\"" + escapedLabelValue(entry.getValue()) + "\","; builder.append(sanitized); }); + builder.append("}"); return builder.toString(); } @@ -385,8 +380,33 @@ public class StateHandler extends AbstractRequestHandler implements CapabilityRe return name.replaceAll("\\.", "_"); } - private Number sanitizeIfDouble(Number num) { - return num instanceof Double d ? sanitizeDouble(d) : num; + private String sanitizeIfDouble(Number num) { + return num instanceof Double d ? prettyDouble(d) : num.toString(); + } + + private String escapedLabelValue(String labelValue) { + var builder = new StringBuilder(); + for (int i = 0; i < labelValue.length(); i++) { + var c = labelValue.charAt(i); + switch (c) { + case '\n': + builder.append("\\n"); + break; + case '\\': + case '"': + builder.append("\\") + .append(c); + break; + default: + builder.append(c); + } + } + return builder.toString(); + } + + private String prettyDouble(Double d) { + if (Double.isFinite(d) || d.isNaN()) return d.toString(); + return d.equals(Double.NEGATIVE_INFINITY) ? "-Inf" : "Inf"; } private static byte[] toPrettyString(JsonNode resources) throws JsonProcessingException { @@ -419,4 +439,29 @@ public class StateHandler extends AbstractRequestHandler implements CapabilityRe } } + class PrometheusEntry implements Comparable<PrometheusEntry> { + final String metricName; + final String dimensions; + final Number value; + + public PrometheusEntry(String metricName, String dimensions, Number value) { + this.metricName = metricName; + this.dimensions = dimensions; + this.value = value; + } + + @Override + public int compareTo(PrometheusEntry o) { + int comparison = this.metricName.compareTo(o.metricName); + return comparison != 0 ? comparison : this.dimensions.compareTo(o.dimensions); + } + + public void appendPrometheusEntry(StringBuilder builder, long timestamp) { + builder.append(metricName) + .append(dimensions) + .append(" ").append(sanitizeIfDouble(value)).append(" ") + .append(timestamp).append("\n"); + } + } + } diff --git a/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def b/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def index 95b93617b6f..2906f75a1f5 100644 --- a/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def +++ b/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def @@ -123,6 +123,8 @@ healthCheckProxy.cacheExpiry double default=1.0 proxyProtocol.enabled bool default=false # Allow https in parallel with proxy protocol +# TODO Vespa 9 Remove +# Unused since 8.327 proxyProtocol.mixedMode bool default=false # Maximum number of request per connection before server marks connections as non-persistent. Set to '0' to disable. diff --git a/container-core/src/test/java/com/yahoo/container/jdisc/state/StateHandlerTest.java b/container-core/src/test/java/com/yahoo/container/jdisc/state/StateHandlerTest.java index 3d1a4a3583e..c99a61781cb 100644 --- a/container-core/src/test/java/com/yahoo/container/jdisc/state/StateHandlerTest.java +++ b/container-core/src/test/java/com/yahoo/container/jdisc/state/StateHandlerTest.java @@ -80,28 +80,34 @@ public class StateHandlerTest extends StateHandlerTestBase { @Test public void testPrometheusFormat() { var counterContext = StateMetricContext.newInstance(Map.of("label1", "val1", "label2", "val2")); + var otherContext = StateMetricContext.newInstance(Map.of( + "label1", "This label has \"quotes\"", + "label2", "This label, a\nnewline")); var snapshot = new MetricSnapshot(0L, SNAPSHOT_INTERVAL, TimeUnit.MILLISECONDS); - snapshot.set(null, "bar", 20); - snapshot.set(null, "bar", 40); snapshot.add(counterContext, "some.counter", 10); snapshot.add(counterContext, "some.counter", 20); + snapshot.add(otherContext, "some.counter", 1); + snapshot.add(otherContext, "some.counter", 2); + snapshot.set(null, "bar", 20); + snapshot.set(null, "bar", 40); + snapshot.set(null, "testing.infinity", Double.NEGATIVE_INFINITY); + snapshot.set(null, "testing.nan", Double.NaN); snapshotProvider.setSnapshot(snapshot); var response = requestAsString(V1_URI + "metrics?format=prometheus"); var expectedResponse = """ # NOTE: THIS API IS NOT INTENDED FOR PUBLIC USE - # HELP bar_max - # TYPE bar_max untyped - bar_max{} 40.0 300000 - # HELP bar_sum - # TYPE bar_sum untyped - bar_sum{} 60.0 300000 - # HELP bar_count - # TYPE bar_count untyped - bar_count{} 2 300000 - # HELP some_counter_count - # TYPE some_counter_count untyped + bar_count 2 300000 + bar_max 40.0 300000 + bar_sum 60.0 300000 + some_counter_count{label1="This label has \\"quotes\\"",label2="This label, a\\nnewline",} 3 300000 some_counter_count{label1="val1",label2="val2",} 30 300000 + testing_infinity_count 1 300000 + testing_infinity_max -Inf 300000 + testing_infinity_sum -Inf 300000 + testing_nan_count 1 300000 + testing_nan_max NaN 300000 + testing_nan_sum NaN 300000 """; assertEquals(expectedResponse, response); } diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/DataplaneProxyService.java b/container-disc/src/main/java/com/yahoo/container/jdisc/DataplaneProxyService.java index d94244b0e47..e1a753ddf27 100644 --- a/container-disc/src/main/java/com/yahoo/container/jdisc/DataplaneProxyService.java +++ b/container-disc/src/main/java/com/yahoo/container/jdisc/DataplaneProxyService.java @@ -134,7 +134,7 @@ public class DataplaneProxyService extends AbstractComponent { } else { if (state == NginxState.RELOAD_REQUIRED) { try { - proxyCommands.reload(); + proxyCommands.reload(nginxConf); changeState(convergeTo); } catch (Exception e) { logger.log(Level.INFO, "Failed to reconfigure nginx, will retry."); @@ -148,7 +148,7 @@ public class DataplaneProxyService extends AbstractComponent { } else if (convergeTo == NginxState.STOPPED) { if (proxyCommands.isRunning()) { try { - proxyCommands.stop(); + proxyCommands.stop(nginxConf); } catch (Exception e) { logger.log(Level.INFO, "Failed to stop nginx, will retry"); logger.log(Level.FINE, "Exception from nginx stop", e); @@ -240,8 +240,8 @@ public class DataplaneProxyService extends AbstractComponent { public interface ProxyCommands { void start(Path configFile); - void stop(); - void reload(); + void stop(Path configFile); + void reload(Path configFile); boolean isRunning(); } @@ -264,11 +264,12 @@ public class DataplaneProxyService extends AbstractComponent { } @Override - public void stop() { + public void stop(Path configFile) { try { Process stopCommand = new ProcessBuilder().command( "nginx", - "-s", "stop" + "-s", "stop", + "-c", configFile.toString() ).start(); int exitCode = stopCommand.waitFor(); if (exitCode != 0) { @@ -281,11 +282,12 @@ public class DataplaneProxyService extends AbstractComponent { } @Override - public void reload() { + public void reload(Path configFile) { try { Process reloadCommand = new ProcessBuilder().command( "nginx", - "-s", "reload" + "-s", "reload", + "-c", configFile.toString() ).start(); int exitCode = reloadCommand.waitFor(); if (exitCode != 0) { diff --git a/container-disc/src/test/java/com/yahoo/container/jdisc/DataplaneProxyServiceTest.java b/container-disc/src/test/java/com/yahoo/container/jdisc/DataplaneProxyServiceTest.java index 719a6c0af85..47ff646918d 100644 --- a/container-disc/src/test/java/com/yahoo/container/jdisc/DataplaneProxyServiceTest.java +++ b/container-disc/src/test/java/com/yahoo/container/jdisc/DataplaneProxyServiceTest.java @@ -67,7 +67,7 @@ public class DataplaneProxyServiceTest { @Test public void retries_reload_errors() throws IOException { - Mockito.doThrow(new RuntimeException("IO error")).doNothing().when(proxyCommandsMock).reload(); + Mockito.doThrow(new RuntimeException("IO error")).doNothing().when(proxyCommandsMock).reload(any()); when(proxyCommandsMock.isRunning()).thenReturn(false); DataplaneProxyService service = dataplaneProxyService(proxyCommandsMock); @@ -83,7 +83,7 @@ public class DataplaneProxyServiceTest { assertEquals(DataplaneProxyService.NginxState.RELOAD_REQUIRED, service.state()); service.converge(); assertEquals(DataplaneProxyService.NginxState.RUNNING, service.state()); - verify(proxyCommandsMock, times(2)).reload(); + verify(proxyCommandsMock, times(2)).reload(any()); } @Test @@ -98,7 +98,7 @@ public class DataplaneProxyServiceTest { assertTrue(proxyCommands.isRunning()); // Simulate nginx process dying - proxyCommands.stop(); + proxyCommands.stop(null); assertFalse(proxyCommands.isRunning()); service.converge(); assertTrue(proxyCommands.isRunning()); @@ -136,7 +136,7 @@ public class DataplaneProxyServiceTest { reset(proxyCommandsMock); when(mockProxyCommands.isRunning()).thenReturn(true).thenReturn(false); - doThrow(new RuntimeException("Failed to stop proxy")).when(proxyCommandsMock).stop(); + doThrow(new RuntimeException("Failed to stop proxy")).when(proxyCommandsMock).stop(any()); Thread thread = new Thread(service::deconstruct);// deconstruct will block until nginx is stopped thread.start(); @@ -151,7 +151,7 @@ public class DataplaneProxyServiceTest { assertEquals(service.state(), DataplaneProxyService.NginxState.STOPPED); thread.join(); - verify(mockProxyCommands, times(1)).stop(); + verify(mockProxyCommands, times(1)).stop(any()); } private DataplaneProxyService dataplaneProxyService(DataplaneProxyService.ProxyCommands proxyCommands) throws IOException { @@ -190,12 +190,12 @@ public class DataplaneProxyServiceTest { } @Override - public void stop() { + public void stop(Path configFile) { running = false; } @Override - public void reload() { + public void reload(Path configFile) { } diff --git a/container-llama/CMakeLists.txt b/container-llama/CMakeLists.txt new file mode 100644 index 00000000000..ba41a4ef835 --- /dev/null +++ b/container-llama/CMakeLists.txt @@ -0,0 +1,2 @@ +# Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +install_jar(container-llama.jar) diff --git a/container-llama/README.md b/container-llama/README.md new file mode 100644 index 00000000000..3f172726124 --- /dev/null +++ b/container-llama/README.md @@ -0,0 +1,4 @@ +<!-- Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +# container-llama + +llama repackaged as a bundle diff --git a/container-llama/pom.xml b/container-llama/pom.xml new file mode 100644 index 00000000000..1eb057abcaf --- /dev/null +++ b/container-llama/pom.xml @@ -0,0 +1,97 @@ +<?xml version="1.0"?> +<!-- Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>container-llama</artifactId> + <packaging>container-plugin</packaging> + <version>8-SNAPSHOT</version> + <parent> + <groupId>com.yahoo.vespa</groupId> + <artifactId>parent</artifactId> + <version>8-SNAPSHOT</version> + <relativePath>../parent/pom.xml</relativePath> + </parent> + <properties> + <maven.javadoc.skip>true</maven.javadoc.skip> <!-- Javadoc plugin fails because of no source code in module --> + </properties> + <dependencies> + <!-- provided --> + <dependency> + <groupId>com.yahoo.vespa</groupId> + <artifactId>annotations</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <!-- Not directly used in this module, but needed to get Import-Packages for JDK packages it exports. --> + <groupId>com.yahoo.vespa</groupId> + <artifactId>jdisc_core</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <!-- compile --> + <dependency> + <groupId>de.kherud</groupId> + <artifactId>llama</artifactId> + <scope>compile</scope> + <exclusions> + <exclusion> + <groupId>org.jetbrains</groupId> + <artifactId>annotations</artifactId> + </exclusion> + </exclusions> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>com.yahoo.vespa</groupId> + <artifactId>bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <bundleType>CORE</bundleType> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + <configuration> + <minimizeJar>false</minimizeJar> + <createDependencyReducedPom>false</createDependencyReducedPom> + <filters> + <filter> + <artifact>de.kherud:*</artifact> + <excludes> + <exclude>de/kherud/llama/Linux-Android//**</exclude> + <exclude>de/kherud/llama/Linux/**</exclude> + <exclude>de/kherud/llama/Mac/**</exclude> + <exclude>de/kherud/llama/Windows/**</exclude> + </excludes> + </filter> + </filters> + <transformers> + <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> + <manifestEntries> + <Bundle-Activator>ai.vespa.llama.LlamaBundleActivator</Bundle-Activator> + </manifestEntries> + </transformer> + </transformers> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/container-llama/src/main/java/ai/vespa/llama/LlamaBundleActivator.java b/container-llama/src/main/java/ai/vespa/llama/LlamaBundleActivator.java new file mode 100644 index 00000000000..11ba05e363d --- /dev/null +++ b/container-llama/src/main/java/ai/vespa/llama/LlamaBundleActivator.java @@ -0,0 +1,51 @@ +// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +package ai.vespa.llama; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +import java.util.logging.Logger; + +/** + * @author arnej + * Finds native libraries when the bundle is activated. + **/ +public class LlamaBundleActivator implements BundleActivator { + + private static final String PATH_PROPNAME = "de.kherud.llama.lib.path"; + private static final Logger log = Logger.getLogger(LlamaBundleActivator.class.getName()); + + @Override + public void start(BundleContext ctx) { + log.fine("start bundle"); + if (checkFilenames( + "/dev/nvidia0", + "/opt/vespa-deps/lib64/cuda/libllama.so", + "/opt/vespa-deps/lib64/cuda/libjllama.so")) { + System.setProperty(PATH_PROPNAME, "/opt/vespa-deps/lib64/cuda"); + } else if (checkFilenames( + "/opt/vespa-deps/lib64/libllama.so", + "/opt/vespa-deps/lib64/libjllama.so")) { + System.setProperty(PATH_PROPNAME, "/opt/vespa-deps/lib64"); + } else { + throw new IllegalArgumentException("Cannot find shared libraries"); + } + } + + @Override + public void stop(BundleContext ctx) { + log.fine("stop bundle"); + } + + private boolean checkFilenames(String... filenames) { + for (String fn : filenames) { + var f = new java.io.File(fn); + if (! f.canRead()) { + return false; + } + } + return true; + } + +} diff --git a/container-messagebus/src/main/java/com/yahoo/container/jdisc/messagebus/SessionCache.java b/container-messagebus/src/main/java/com/yahoo/container/jdisc/messagebus/SessionCache.java index 2464a272ed1..3d500c85df1 100644 --- a/container-messagebus/src/main/java/com/yahoo/container/jdisc/messagebus/SessionCache.java +++ b/container-messagebus/src/main/java/com/yahoo/container/jdisc/messagebus/SessionCache.java @@ -106,11 +106,11 @@ public final class SessionCache extends AbstractComponent { return new SharedMessageBus(bus); } - ReferencedResource<SharedIntermediateSession> retainIntermediate(final IntermediateSessionParams p) { + ReferencedResource<SharedIntermediateSession> retainIntermediate(IntermediateSessionParams p) { return intermediatesCreator.retain(intermediateLock, intermediates, p); } - public ReferencedResource<SharedSourceSession> retainSource(final SourceSessionParams p) { + public ReferencedResource<SharedSourceSession> retainSource(SourceSessionParams p) { return sourcesCreator.retain(sourceLock, sources, p); } @@ -137,7 +137,7 @@ public final class SessionCache extends AbstractComponent { try { sessionReference = session.refer(this); logReuse(session); - } catch (final IllegalStateException e) { + } catch (IllegalStateException e) { session = createAndStore(registry, p, key); sessionReference = References.fromResource(session); } @@ -169,7 +169,7 @@ public final class SessionCache extends AbstractComponent { } @Override - void logReuse(final SharedSourceSession session) { + void logReuse(SharedSourceSession session) { log.log(Level.FINE, "Reusing source session."); } } @@ -179,7 +179,7 @@ public final class SessionCache extends AbstractComponent { @Override SharedIntermediateSession create(IntermediateSessionParams p) { - log.log(Level.FINE, "Creating new intermediate session " + p.getName() + ""); + log.log(Level.FINE, "Creating new intermediate session " + p.getName()); return bus().newIntermediateSession(p); } @@ -190,7 +190,7 @@ public final class SessionCache extends AbstractComponent { @Override void logReuse(SharedIntermediateSession session) { - log.log(Level.FINE, "Reusing intermediate session " + session.name() + ""); + log.log(Level.FINE, "Reusing intermediate session " + session.name()); } } @@ -203,12 +203,12 @@ public final class SessionCache extends AbstractComponent { } - static class StaticThrottlePolicySignature extends ThrottlePolicySignature { + static final class StaticThrottlePolicySignature extends ThrottlePolicySignature { private final int maxPendingCount; private final long maxPendingSize; - StaticThrottlePolicySignature(final StaticThrottlePolicy policy) { + StaticThrottlePolicySignature(StaticThrottlePolicy policy) { maxPendingCount = policy.getMaxPendingCount(); maxPendingSize = policy.getMaxPendingSize(); } @@ -224,26 +224,15 @@ public final class SessionCache extends AbstractComponent { } @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (getClass() != obj.getClass()) { - return false; - } - final StaticThrottlePolicySignature other = (StaticThrottlePolicySignature) obj; - if (maxPendingCount != other.maxPendingCount) { - return false; - } - if (maxPendingSize != other.maxPendingSize) { - return false; - } - return true; + public boolean equals(Object obj) { + if (this == obj) return true; + if (! (obj instanceof StaticThrottlePolicySignature other)) return false; + return (maxPendingCount == other.maxPendingCount) && (maxPendingSize == other.maxPendingSize); } } - static class DynamicThrottlePolicySignature extends ThrottlePolicySignature { + static final class DynamicThrottlePolicySignature extends ThrottlePolicySignature { private final int maxPending; private final double maxWindowSize; @@ -251,7 +240,7 @@ public final class SessionCache extends AbstractComponent { private final double windowSizeBackoff; private final double windowSizeIncrement; - DynamicThrottlePolicySignature(final DynamicThrottlePolicy policy) { + DynamicThrottlePolicySignature(DynamicThrottlePolicy policy) { maxPending = policy.getMaxPendingCount(); maxWindowSize = policy.getMaxWindowSize(); minWindowSize = policy.getMinWindowSize(); @@ -278,29 +267,13 @@ public final class SessionCache extends AbstractComponent { @Override public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (getClass() != obj.getClass()) { - return false; - } - DynamicThrottlePolicySignature other = (DynamicThrottlePolicySignature) obj; - if (maxPending != other.maxPending) { - return false; - } - if (Double.doubleToLongBits(maxWindowSize) != Double.doubleToLongBits(other.maxWindowSize)) { - return false; - } - if (Double.doubleToLongBits(minWindowSize) != Double - .doubleToLongBits(other.minWindowSize)) { - return false; - } - if (Double.doubleToLongBits(windowSizeBackoff) != Double.doubleToLongBits(other.windowSizeBackoff)) { - return false; - } - if (Double.doubleToLongBits(windowSizeIncrement) != Double.doubleToLongBits(other.windowSizeIncrement)) { - return false; - } + if (this == obj) return true; + if (! (obj instanceof DynamicThrottlePolicySignature other)) return false; + if (maxPending != other.maxPending) return false; + if (Double.doubleToLongBits(maxWindowSize) != Double.doubleToLongBits(other.maxWindowSize)) return false; + if (Double.doubleToLongBits(minWindowSize) != Double.doubleToLongBits(other.minWindowSize)) return false; + if (Double.doubleToLongBits(windowSizeBackoff) != Double.doubleToLongBits(other.windowSizeBackoff)) return false; + if (Double.doubleToLongBits(windowSizeIncrement) != Double.doubleToLongBits(other.windowSizeIncrement)) return false; return true; } diff --git a/container-search/src/test/java/ai/vespa/search/llm/LLMSearcherTest.java b/container-search/src/test/java/ai/vespa/search/llm/LLMSearcherTest.java index 11311ad9d9d..1efcf1c736a 100755 --- a/container-search/src/test/java/ai/vespa/search/llm/LLMSearcherTest.java +++ b/container-search/src/test/java/ai/vespa/search/llm/LLMSearcherTest.java @@ -121,7 +121,7 @@ public class LLMSearcherTest { @Test public void testAsyncGeneration() { - var executor = Executors.newFixedThreadPool(1); + var executor = Executors.newFixedThreadPool(2); var sb = new StringBuilder(); try { var config = new LlmSearcherConfig.Builder().stream(false).providerId("mock").build(); // config says don't stream... diff --git a/dependency-versions/pom.xml b/dependency-versions/pom.xml index 5615fec8795..da857b25475 100644 --- a/dependency-versions/pom.xml +++ b/dependency-versions/pom.xml @@ -66,8 +66,8 @@ <assertj.vespa.version>3.25.3</assertj.vespa.version> <!-- Athenz dependencies. Make sure these dependencies match those in Vespa's internal repositories --> - <aws-sdk.vespa.version>1.12.691</aws-sdk.vespa.version> - <athenz.vespa.version>1.11.54</athenz.vespa.version> + <aws-sdk.vespa.version>1.12.693</aws-sdk.vespa.version> + <athenz.vespa.version>1.11.55</athenz.vespa.version> <!-- Athenz END --> <!-- WARNING: If you change curator version, you also need to update @@ -115,9 +115,10 @@ <junit.vespa.version>5.10.2</junit.vespa.version> <junit.platform.vespa.version>1.10.2</junit.platform.vespa.version> <junit4.vespa.version>4.13.2</junit4.vespa.version> - <luben.zstd.vespa.version>1.5.5-11</luben.zstd.vespa.version> + <kherud.llama.vespa.version>2.3.5</kherud.llama.vespa.version> + <luben.zstd.vespa.version>1.5.6-1</luben.zstd.vespa.version> <lucene.vespa.version>9.10.0</lucene.vespa.version> - <maven-archiver.vespa.version>3.6.1</maven-archiver.vespa.version> + <maven-archiver.vespa.version>3.6.2</maven-archiver.vespa.version> <maven-wagon.vespa.version>3.5.3</maven-wagon.vespa.version> <mimepull.vespa.version>1.10.0</mimepull.vespa.version> <mockito.vespa.version>5.11.0</mockito.vespa.version> @@ -130,7 +131,9 @@ <org.json.vespa.version>20240303</org.json.vespa.version> <org.lz4.vespa.version>1.8.0</org.lz4.vespa.version> <prometheus.client.vespa.version>0.16.0</prometheus.client.vespa.version> + <plexus-archiver.vespa.version>4.9.2</plexus-archiver.vespa.version> <plexus-interpolation.vespa.version>1.27</plexus-interpolation.vespa.version> + <plexus-io.vespa.version>3.4.2</plexus-io.vespa.version> <plexus-utils.vespa.version>3.5.1</plexus-utils.vespa.version> <plexus-xml.vespa.version>3.0.0</plexus-xml.vespa.version> <protobuf.vespa.version>3.25.3</protobuf.vespa.version> diff --git a/dist/vespa.spec b/dist/vespa.spec index 53e82e372af..4886bd43db8 100644 --- a/dist/vespa.spec +++ b/dist/vespa.spec @@ -629,6 +629,7 @@ fi %{_prefix}/lib/jars/config-provisioning-jar-with-dependencies.jar %{_prefix}/lib/jars/container-apache-http-client-bundle-jar-with-dependencies.jar %{_prefix}/lib/jars/container-disc-jar-with-dependencies.jar +%{_prefix}/lib/jars/container-llama.jar %{_prefix}/lib/jars/container-onnxruntime.jar %{_prefix}/lib/jars/container-search-and-docproc-jar-with-dependencies.jar %{_prefix}/lib/jars/container-spifly.jar diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java index 0b30901bb89..9606a2b88ba 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java @@ -195,7 +195,7 @@ public class Flags { // TODO: Move to a permanent flag public static final UnboundListFlag<String> ALLOWED_ATHENZ_PROXY_IDENTITIES = defineListFlag( "allowed-athenz-proxy-identities", List.of(), String.class, - List.of("bjorncs", "tokle"), "2021-02-10", "2024-04-01", + List.of("bjorncs", "tokle"), "2021-02-10", "2024-10-01", "Allowed Athenz proxy identities", "takes effect at redeployment"); @@ -256,7 +256,7 @@ public class Flags { public static final UnboundBooleanFlag ENABLE_PROXY_PROTOCOL_MIXED_MODE = defineFeatureFlag( "enable-proxy-protocol-mixed-mode", true, - List.of("tokle"), "2022-05-09", "2024-04-01", + List.of("tokle"), "2022-05-09", "2024-10-01", "Enable or disable proxy protocol mixed mode", "Takes effect on redeployment", INSTANCE_ID); diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/ExpressionOptimizer.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/ExpressionOptimizer.java index bad8b94d074..a66c47caa85 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/ExpressionOptimizer.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/ExpressionOptimizer.java @@ -1,7 +1,22 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.indexinglanguage; -import com.yahoo.vespa.indexinglanguage.expressions.*; + +import com.yahoo.vespa.indexinglanguage.expressions.CompositeExpression; +import com.yahoo.vespa.indexinglanguage.expressions.ConstantExpression; +import com.yahoo.vespa.indexinglanguage.expressions.EchoExpression; +import com.yahoo.vespa.indexinglanguage.expressions.Expression; +import com.yahoo.vespa.indexinglanguage.expressions.ForEachExpression; +import com.yahoo.vespa.indexinglanguage.expressions.GetVarExpression; +import com.yahoo.vespa.indexinglanguage.expressions.HostNameExpression; +import com.yahoo.vespa.indexinglanguage.expressions.InputExpression; +import com.yahoo.vespa.indexinglanguage.expressions.NowExpression; +import com.yahoo.vespa.indexinglanguage.expressions.OutputExpression; +import com.yahoo.vespa.indexinglanguage.expressions.RandomExpression; +import com.yahoo.vespa.indexinglanguage.expressions.ScriptExpression; +import com.yahoo.vespa.indexinglanguage.expressions.SetVarExpression; +import com.yahoo.vespa.indexinglanguage.expressions.StatementExpression; +import com.yahoo.vespa.indexinglanguage.expressions.SwitchExpression; import java.util.ArrayList; import java.util.List; @@ -59,7 +74,7 @@ public class ExpressionOptimizer extends ExpressionConverter { } static boolean ignoresInput(Expression exp) { - if (exp instanceof SwitchExpression || exp instanceof ScriptExpression || exp instanceof ForEachExpression ) { + if (exp instanceof SwitchExpression || exp instanceof ScriptExpression || exp instanceof ForEachExpression) { return false; // Switch and script never ignores input. } if (exp instanceof CompositeExpression) { diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/BusyWaitExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/BusyWaitExpression.java new file mode 100644 index 00000000000..8ae77aad1b1 --- /dev/null +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/BusyWaitExpression.java @@ -0,0 +1,43 @@ +package com.yahoo.vespa.indexinglanguage.expressions; + +import com.yahoo.document.DataType; +import com.yahoo.document.datatypes.FieldValue; +import com.yahoo.document.datatypes.NumericFieldValue; + +/** + * Utility expression that will busy-wait the amount of time given in the numeric field. + * Non-numeric fields will be ignored + * @author baldersheim + */ +public final class BusyWaitExpression extends Expression { + public BusyWaitExpression() { + super(UnresolvedDataType.INSTANCE); + } + + private static double nihlakanta(int i) { + long a = 2 + i * 4L; + return (24 * (a+2))/(double)(a*(a+1)*(a+2)*(a+3)); + } + + @Override + protected void doExecute(ExecutionContext context) { + FieldValue value = context.getValue(); + if (value instanceof NumericFieldValue num) { + double napSecs = num.getNumber().doubleValue(); + long doom = System.nanoTime() + (long)(1_000_000_000.0 * napSecs); + while (doom > System.nanoTime()) { + double pi = 3; + for (int i = 0; i < 1000; i++) { + pi += nihlakanta(i); + } + context.getCache().put("Busy wait computing pi and store it to avoid jit optiming it away", pi); + } + } + } + + @Override protected void doVerify(VerificationContext context) { } + @Override public DataType createdOutputType() { return null; } + @Override public String toString() { return "busy_wait"; } + @Override public boolean equals(Object obj) { return obj instanceof BusyWaitExpression; } + @Override public int hashCode() { return getClass().hashCode(); } +} diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/EchoExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/EchoExpression.java index 690e7415801..4001e2a6fd0 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/EchoExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/EchoExpression.java @@ -27,7 +27,7 @@ public final class EchoExpression extends Expression { @Override protected void doExecute(ExecutionContext context) { - out.println(String.valueOf(context.getValue())); + out.println(context.getValue()); } @Override @@ -47,14 +47,9 @@ public final class EchoExpression extends Expression { @Override public boolean equals(Object obj) { - if (!(obj instanceof EchoExpression)) { - return false; - } - EchoExpression rhs = (EchoExpression)obj; - if (out != rhs.out) { - return false; - } - return true; + if (!(obj instanceof EchoExpression rhs)) return false; + + return out == rhs.out; } @Override diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SleepExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SleepExpression.java new file mode 100644 index 00000000000..f7216fc1c97 --- /dev/null +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SleepExpression.java @@ -0,0 +1,36 @@ +package com.yahoo.vespa.indexinglanguage.expressions; + +import com.yahoo.document.DataType; +import com.yahoo.document.datatypes.FieldValue; +import com.yahoo.document.datatypes.NumericFieldValue; + +/** + * Utility expression that will sleep the amount of time given in the numeric field. + * Non-numeric fields will be ignored + * @author baldersheim + */ +public final class SleepExpression extends Expression { + public SleepExpression() { + super(UnresolvedDataType.INSTANCE); + } + + @Override + protected void doExecute(ExecutionContext context) { + FieldValue value = context.getValue(); + if (value instanceof NumericFieldValue num) { + double napSecs = num.getNumber().doubleValue(); + long nanos = (long)(napSecs*1_000_000_000.0); + try { + Thread.sleep(nanos / 1_000_000, (int) (nanos % 1_000_000)); + } catch (InterruptedException e) { + // Do nothing + } + } + } + + @Override protected void doVerify(VerificationContext context) { } + @Override public DataType createdOutputType() { return null; } + @Override public String toString() { return "sleep"; } + @Override public boolean equals(Object obj) { return obj instanceof SleepExpression; } + @Override public int hashCode() { return getClass().hashCode(); } +} diff --git a/indexinglanguage/src/main/javacc/IndexingParser.jj b/indexinglanguage/src/main/javacc/IndexingParser.jj index a3b4039408a..469d96ead60 100644 --- a/indexinglanguage/src/main/javacc/IndexingParser.jj +++ b/indexinglanguage/src/main/javacc/IndexingParser.jj @@ -149,6 +149,7 @@ TOKEN : <ATTRIBUTE: "attribute"> | <BASE64_DECODE: "base64decode"> | <BASE64_ENCODE: "base64encode"> | + <BUSY_WAIT: "busy_wait"> | <CASE: "case"> | <CASE_DEFAULT: "default"> | <CLEAR_STATE: "clear_state"> | @@ -183,6 +184,7 @@ TOKEN : <SELECT_INPUT: "select_input"> | <SET_LANGUAGE: "set_language"> | <SET_VAR: "set_var"> | + <SLEEP: "sleep"> | <SPLIT: "split"> | <STEM: "stem"> | <SUBSTRING: "substring"> | @@ -296,6 +298,7 @@ Expression value() : ( val = attributeExp() | val = base64DecodeExp() | val = base64EncodeExp() | + val = busy_waitExp() | val = clearStateExp() | val = echoExp() | val = embedExp() | @@ -325,6 +328,7 @@ Expression value() : val = setLanguageExp() | val = setValueExp() | val = setVarExp() | + val = sleepExp() | val = splitExp() | val = substringExp() | val = summaryExp() | @@ -371,6 +375,12 @@ Expression base64EncodeExp() : { } { return new Base64EncodeExpression(); } } +Expression busy_waitExp() : { } +{ + ( <BUSY_WAIT> ) + { return new BusyWaitExpression(); } +} + Expression clearStateExp() : { } { ( <CLEAR_STATE> ) @@ -608,6 +618,12 @@ Expression setVarExp() : { return new SetVarExpression(val); } } +Expression sleepExp() : { } +{ + ( <SLEEP> ) + { return new SleepExpression(); } +} + Expression splitExp() : { String val; @@ -783,6 +799,7 @@ String identifier() : ( <ATTRIBUTE> | <BASE64_DECODE> | <BASE64_ENCODE> | + <BUSY_WAIT> | <CASE> | <CASE_DEFAULT> | <CLEAR_STATE> | @@ -817,6 +834,7 @@ String identifier() : <SELECT_INPUT> | <SET_LANGUAGE> | <SET_VAR> | + <SLEEP> | <SPLIT> | <STEM> | <SUBSTRING> | diff --git a/maven-plugins/allowed-maven-dependencies.txt b/maven-plugins/allowed-maven-dependencies.txt index e3414b48ee6..bef72f582e4 100644 --- a/maven-plugins/allowed-maven-dependencies.txt +++ b/maven-plugins/allowed-maven-dependencies.txt @@ -45,12 +45,12 @@ org.apache.maven:maven-resolver-provider:${maven-core.vespa.version} org.apache.maven:maven-settings-builder:${maven-core.vespa.version} org.apache.maven:maven-settings:${maven-core.vespa.version} org.apiguardian:apiguardian-api:${apiguardian.vespa.version} -org.codehaus.plexus:plexus-archiver:4.8.0 +org.codehaus.plexus:plexus-archiver:${plexus-archiver.vespa.version} org.codehaus.plexus:plexus-cipher:2.0 org.codehaus.plexus:plexus-classworlds:2.7.0 org.codehaus.plexus:plexus-component-annotations:2.1.0 org.codehaus.plexus:plexus-interpolation:${plexus-interpolation.vespa.version} -org.codehaus.plexus:plexus-io:${maven-enforcer-plugin.vespa.version} +org.codehaus.plexus:plexus-io:${plexus-io.vespa.version} org.codehaus.plexus:plexus-sec-dispatcher:2.0 org.codehaus.plexus:plexus-utils:${plexus-utils.vespa.version} org.codehaus.plexus:plexus-xml:${plexus-xml.vespa.version} diff --git a/messagebus/src/main/java/com/yahoo/messagebus/DynamicThrottlePolicy.java b/messagebus/src/main/java/com/yahoo/messagebus/DynamicThrottlePolicy.java index 76287d949b7..97f681404e9 100644 --- a/messagebus/src/main/java/com/yahoo/messagebus/DynamicThrottlePolicy.java +++ b/messagebus/src/main/java/com/yahoo/messagebus/DynamicThrottlePolicy.java @@ -133,11 +133,9 @@ public class DynamicThrottlePolicy extends StaticThrottlePolicy { // No need to increase window when we're this close to max. // TODO jonmv: Not so sure — what if we're too high, and should back off? } else if (throughput > localMaxThroughput) { - localMaxThroughput = throughput; windowSize += weight * windowSizeIncrement; - if (log.isLoggable(Level.FINE)) { - log.log(Level.FINE, "windowSize " + windowSize + " throughput " + throughput + " local max " + localMaxThroughput); - } + log.log(Level.FINE, () -> "windowSize " + windowSize + " throughput " + throughput + " local max " + localMaxThroughput); + localMaxThroughput = throughput; } else { // scale up/down throughput for comparing to window size double period = 1; @@ -154,9 +152,7 @@ public class DynamicThrottlePolicy extends StaticThrottlePolicy { } else { windowSize += weight * windowSizeIncrement; } - if (log.isLoggable(Level.FINE)) { - log.log(Level.FINE, "windowSize " + windowSize + " throughput " + throughput + " local max " + localMaxThroughput + " efficiency " + efficiency); - } + log.log(Level.FINE, () ->"windowSize " + windowSize + " throughput " + throughput + " local max " + localMaxThroughput + " efficiency " + efficiency); } windowSize = Math.max(minWindowSize, windowSize); windowSize = Math.min(maxWindowSize, windowSize); diff --git a/parent/pom.xml b/parent/pom.xml index ca399019aa6..b21e9b844f5 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -594,6 +594,11 @@ <version>${onnxruntime.vespa.version}</version> </dependency> <dependency> + <groupId>de.kherud</groupId> + <artifactId>llama</artifactId> + <version>${kherud.llama.vespa.version}</version> + </dependency> + <dependency> <groupId>com.yahoo.athenz</groupId> <artifactId>athenz-cert-refresher</artifactId> <version>${athenz.vespa.version}</version> @@ -998,11 +1003,21 @@ </dependency> <dependency> <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-archiver</artifactId> + <version>${plexus-archiver.vespa.version}</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> <artifactId>plexus-interpolation</artifactId> <version>${plexus-interpolation.vespa.version}</version> </dependency> <dependency> <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-io</artifactId> + <version>${plexus-io.vespa.version}</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> <artifactId>plexus-utils</artifactId> <version>${plexus-utils.vespa.version}</version> </dependency> @@ -56,6 +56,7 @@ <module>container-dev</module> <module>container-disc</module> <module>container-documentapi</module> + <module>container-llama</module> <module>container-messagebus</module> <module>container-onnxruntime</module> <module>container-search-and-docproc</module> diff --git a/searchlib/src/tests/queryeval/blueprint/blueprint_test.cpp b/searchlib/src/tests/queryeval/blueprint/blueprint_test.cpp index d556d997206..bb79ad85cc0 100644 --- a/searchlib/src/tests/queryeval/blueprint/blueprint_test.cpp +++ b/searchlib/src/tests/queryeval/blueprint/blueprint_test.cpp @@ -658,6 +658,7 @@ getExpectedBlueprint() " strict_cost: 0\n" " sourceId: 4294967295\n" " docid_limit: 0\n" + " strict: false\n" " children: std::vector {\n" " [0]: (anonymous namespace)::MyTerm {\n" " isTermLike: true\n" @@ -680,6 +681,7 @@ getExpectedBlueprint() " strict_cost: 0\n" " sourceId: 4294967295\n" " docid_limit: 0\n" + " strict: false\n" " }\n" " }\n" "}\n"; @@ -712,6 +714,7 @@ getExpectedSlimeBlueprint() { " strict_cost: 0.0," " sourceId: 4294967295," " docid_limit: 0," + " strict: false," " children: {" " '[type]': 'std::vector'," " '[0]': {" @@ -738,7 +741,8 @@ getExpectedSlimeBlueprint() { " cost: 0.0," " strict_cost: 0.0," " sourceId: 4294967295," - " docid_limit: 0" + " docid_limit: 0," + " strict: false" " }" " }" "}"; diff --git a/searchlib/src/tests/queryeval/blueprint/intermediate_blueprints_test.cpp b/searchlib/src/tests/queryeval/blueprint/intermediate_blueprints_test.cpp index d3b6a90e5db..72dd2b5a4ad 100644 --- a/searchlib/src/tests/queryeval/blueprint/intermediate_blueprints_test.cpp +++ b/searchlib/src/tests/queryeval/blueprint/intermediate_blueprints_test.cpp @@ -555,6 +555,13 @@ void compare(const Blueprint &bp1, const Blueprint &bp2, bool expect_eq) { check_value(a.asDouble()); check_value(b.asDouble()); return true; + } else if (field == "strict") { + // ignore strict-tagging differences between optimized and unoptimized blueprint trees + if (a.type().getId() == vespalib::slime::BOOL::ID && + b.type().getId() == vespalib::slime::BOOL::ID) + { + return true; + } } } if (expect_eq) { diff --git a/searchlib/src/tests/queryeval/flow/queryeval_flow_test.cpp b/searchlib/src/tests/queryeval/flow/queryeval_flow_test.cpp index a4b05d6540c..ed23aaad226 100644 --- a/searchlib/src/tests/queryeval/flow/queryeval_flow_test.cpp +++ b/searchlib/src/tests/queryeval/flow/queryeval_flow_test.cpp @@ -45,6 +45,10 @@ std::vector<FlowStats> gen_data(size_t size) { } void re_seed() { gen_data(0); } +size_t count_perms(size_t n) { + return (n <= 1) ? 1 : count_perms(n-1) * n; +}; + template <typename T, typename F> void each_perm(std::vector<T> &data, size_t k, F fun) { if (k <= 1) { @@ -392,33 +396,48 @@ TEST(FlowTest, optimal_and_not_flow) { void test_strict_AND_sort_strategy(auto my_sort) { re_seed(); - size_t cnt = 64; - double max_rel_err = 0.0; - double sum_rel_err = 0.0; - for (size_t i = 0; i < cnt; ++i) { - auto data = gen_data(7); - double ref_est = AndFlow::estimate_of(data); - double min_cost = 1'000'000.0; - double max_cost = 0.0; - my_sort(data); - double est_cost = ordered_cost_of<AndFlow>(data, true, true); - auto check = [&](const std::vector<FlowStats> &my_data) noexcept { - double my_cost = ordered_cost_of<AndFlow>(my_data, true, true); - min_cost = std::min(min_cost, my_cost); - max_cost = std::max(max_cost, my_cost); - }; - each_perm(data, check); - double rel_err = 0.0; - double cost_range = (max_cost - min_cost); - if (cost_range > 1e-9) { - rel_err = (est_cost - min_cost) / cost_range; + // size_t max_work = 500'000'000; + size_t max_work = 1; + for (size_t child_cnt: {2, 3, 5, 7, 9}) { + size_t cnt = std::max(size_t(10), std::min(size_t(128'000), (max_work / count_perms(child_cnt)))); + double max_rel_err = 0.0; + double sum_rel_err = 0.0; + std::vector<double> errs; + errs.reserve(cnt); + auto p = [&](double arg){ + size_t idx = std::lround(arg * (errs.size() - 1)); + if (idx < errs.size()) { + return errs[idx]; + } + return errs.back(); + }; + for (size_t i = 0; i < cnt; ++i) { + auto data = gen_data(child_cnt); + double ref_est = AndFlow::estimate_of(data); + double min_cost = 1'000'000.0; + double max_cost = 0.0; + my_sort(data); + double est_cost = ordered_cost_of<AndFlow>(data, true, true); + auto check = [&](const std::vector<FlowStats> &my_data) noexcept { + double my_cost = ordered_cost_of<AndFlow>(my_data, true, true); + min_cost = std::min(min_cost, my_cost); + max_cost = std::max(max_cost, my_cost); + }; + each_perm(data, check); + double rel_err = 0.0; + double cost_range = (max_cost - min_cost); + if (cost_range > 1e-9) { + rel_err = (est_cost - min_cost) / cost_range; + } + max_rel_err = std::max(max_rel_err, rel_err); + sum_rel_err += rel_err; + errs.push_back(rel_err); + EXPECT_NEAR(ref_est, AndFlow::estimate_of(data), 1e-9); } - max_rel_err = std::max(max_rel_err, rel_err); - sum_rel_err += rel_err; - EXPECT_NEAR(ref_est, AndFlow::estimate_of(data), 1e-9); + std::sort(errs.begin(), errs.end()); + fprintf(stderr, " AND/%zu: avg: %10f, p90: %10f, p99: %10f, p99.9: %10f, max: %10f\n", + child_cnt, (sum_rel_err / cnt), p(0.9), p(0.99), p(0.999), max_rel_err); } - fprintf(stderr, " strict AND allow_force_strict: avg rel_err: %g, max rel_err: %g\n", - sum_rel_err / cnt, max_rel_err); } TEST(FlowTest, strict_and_with_allow_force_strict_basic_order) { @@ -427,8 +446,8 @@ TEST(FlowTest, strict_and_with_allow_force_strict_basic_order) { } void greedy_sort(std::vector<FlowStats> &data, auto flow, auto score_of) { + InFlow in_flow = InFlow(flow.strict(), flow.flow()); for (size_t next = 0; (next + 1) < data.size(); ++next) { - InFlow in_flow = InFlow(flow.strict(), flow.flow()); size_t best_idx = next; double best_score = score_of(in_flow, data[next]); for (size_t i = next + 1; i < data.size(); ++i) { @@ -453,6 +472,27 @@ TEST(FlowTest, strict_and_with_allow_force_strict_greedy_reduction_efficiency) { test_strict_AND_sort_strategy(my_sort); } +TEST(FlowTest, strict_and_with_allow_force_strict_partitioning) { + auto my_sort = [](auto &data) { + AndFlow::sort(data, false); + double rate = 1.0; + size_t a = 0; + for (size_t b = 0; b < data.size(); ++b) { + double est = data[b].estimate; + if (flow::should_force_strict(est, data[b].cost, data[b].strict_cost, rate)) { + auto pos = data.begin() + b; + std::rotate(data.begin() + a, pos, pos + 1); + ++a; + } + rate *= est; + } + if (a == 0) { // need at least 1 strict child + AndFlow::sort(data, true); + } + }; + test_strict_AND_sort_strategy(my_sort); +} + TEST(FlowTest, strict_and_with_allow_force_strict_incremental_strict_selection) { auto my_sort = [](auto &data) { AndFlow::sort(data, true); @@ -461,11 +501,8 @@ TEST(FlowTest, strict_and_with_allow_force_strict_incremental_strict_selection) if (score >= 0.0) { break; } - auto the_one = data[idx]; - for (; idx > next; --idx) { - data[idx] = data[idx-1]; - } - data[next] = the_one; + auto pos = data.begin() + idx; + std::rotate(data.begin() + next, pos, pos + 1); } }; test_strict_AND_sort_strategy(my_sort); @@ -475,16 +512,13 @@ TEST(FlowTest, strict_and_with_allow_force_strict_incremental_strict_selection_w auto my_sort = [](auto &data) { AndFlow::sort(data, true); size_t strict_cnt = 1; - while (strict_cnt < data.size()) { + for (; strict_cnt < data.size(); ++strict_cnt) { auto [idx, score] = flow::select_forced_strict_and_child(flow::DirectAdapter(), data, strict_cnt); if (score >= 0.0) { break; } - auto the_one = data[idx]; - for (; idx > strict_cnt; --idx) { - data[idx] = data[idx-1]; - } - data[strict_cnt++] = the_one; + auto pos = data.begin() + idx; + std::rotate(data.begin() + strict_cnt, pos, pos + 1); } std::sort(data.begin(), data.begin() + strict_cnt, [](const auto &a, const auto &b){ return (a.estimate < b.estimate); }); @@ -492,4 +526,48 @@ TEST(FlowTest, strict_and_with_allow_force_strict_incremental_strict_selection_w test_strict_AND_sort_strategy(my_sort); } +TEST(FlowTest, strict_and_with_allow_force_strict_incremental_strict_selection_with_order) { + auto my_sort = [](auto &data) { + AndFlow::sort(data, true); + for (size_t next = 1; next < data.size(); ++next) { + auto [idx, target, score] = flow::select_forced_strict_and_child_with_order(flow::DirectAdapter(), data, next); + if (score >= 0.0) { + break; + } + auto pos = data.begin() + idx; + std::rotate(data.begin() + target, pos, pos + 1); + } + }; + test_strict_AND_sort_strategy(my_sort); +} + +TEST(FlowTest, strict_and_with_allow_force_strict_assume_strict_then_partition_and_re_sort_non_strict) { + auto my_sort = [](auto &data) { + std::sort(data.begin(), data.end(), + [](const auto &a, const auto &b){ return (a.estimate < b.estimate); }); + double est = 1.0; + size_t last = data.size(); + auto best_strict = [&](size_t i)noexcept{ + if (i == 0) { + return data[i].strict_cost < data[i].cost; + } else { + return flow::should_force_strict(data[i].estimate, data[i].cost, data[i].strict_cost, est); + } + }; + for (size_t i = 0; i < last; ++i) { + while (i < last && !best_strict(i)) { + std::rotate(data.begin()+i, data.begin()+i+1, data.begin()+last); + --last; + } + est *= data[i].estimate; + } + if (last > 0) { + std::sort(data.begin() + last, data.end(), flow::MinAndCost(flow::DirectAdapter())); + } else { + AndFlow::sort(data, true); + } + }; + test_strict_AND_sort_strategy(my_sort); +} + GTEST_MAIN_RUN_ALL_TESTS() diff --git a/searchlib/src/tests/queryeval/parallel_weak_and/parallel_weak_and_test.cpp b/searchlib/src/tests/queryeval/parallel_weak_and/parallel_weak_and_test.cpp index 992ac320385..2bd560637d2 100644 --- a/searchlib/src/tests/queryeval/parallel_weak_and/parallel_weak_and_test.cpp +++ b/searchlib/src/tests/queryeval/parallel_weak_and/parallel_weak_and_test.cpp @@ -635,6 +635,7 @@ TEST(ParallelWeakAndTest, require_that_asString_on_blueprint_works) " strict_cost: 0\n" " sourceId: 4294967295\n" " docid_limit: 0\n" + " strict: false\n" " _weights: std::vector {\n" " [0]: 5\n" " }\n" @@ -660,6 +661,7 @@ TEST(ParallelWeakAndTest, require_that_asString_on_blueprint_works) " strict_cost: 0\n" " sourceId: 4294967295\n" " docid_limit: 0\n" + " strict: false\n" " }\n" " }\n" "}\n"; diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp index 8ffc43928e1..6d79f7bcb26 100644 --- a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp @@ -305,7 +305,7 @@ public: }; double est = OrFlow::estimate_of(MyAdapter(docid_limit), _estimates); return {est, OrFlow::cost_of(MyAdapter(docid_limit), _estimates, false), - OrFlow::cost_of(MyAdapter(docid_limit), _estimates, true) + queryeval::flow::array_cost(est, _estimates.size())}; + OrFlow::cost_of(MyAdapter(docid_limit), _estimates, true) + queryeval::flow::heap_cost(est, _estimates.size())}; } SearchIterator::UP diff --git a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp index 1d323bf298f..73f99d28eda 100644 --- a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp @@ -398,7 +398,7 @@ Blueprint::visitMembers(vespalib::ObjectVisitor &visitor) const visitor.visitFloat("strict_cost", strict_cost()); visitor.visitInt("sourceId", _sourceId); visitor.visitInt("docid_limit", _docid_limit); - // visitor.visitBool("strict", _strict); + visitor.visitBool("strict", _strict); } namespace blueprint { diff --git a/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.cpp index 61ae7b51de1..8b5e76085d2 100644 --- a/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.cpp @@ -72,7 +72,7 @@ EquivBlueprint::calculate_flow_stats(uint32_t docid_limit) const } double est = OrFlow::estimate_of(_terms); return {est, OrFlow::cost_of(_terms, false), - OrFlow::cost_of(_terms, true) + flow::array_cost(est, _terms.size())}; + OrFlow::cost_of(_terms, true) + flow::heap_cost(est, _terms.size())}; } SearchIterator::UP diff --git a/searchlib/src/vespa/searchlib/queryeval/flow.h b/searchlib/src/vespa/searchlib/queryeval/flow.h index f38d447d3b0..98f57a4182d 100644 --- a/searchlib/src/vespa/searchlib/queryeval/flow.h +++ b/searchlib/src/vespa/searchlib/queryeval/flow.h @@ -126,6 +126,11 @@ inline double forced_strict_cost(double estimate, double strict_cost, double rat return 0.2 * (rate - estimate) + strict_cost; } +// would it be faster to force a non-strict child to be strict +inline bool should_force_strict(double estimate, double cost, double strict_cost, double rate) { + return forced_strict_cost(estimate, strict_cost, rate) < (cost * rate); +} + // estimate the absolute cost of evaluating a child with a specific in flow inline double min_child_cost(InFlow in_flow, const FlowStats &stats, bool allow_force_strict) { if (in_flow.strict()) { @@ -231,6 +236,54 @@ auto select_forced_strict_and_child(auto adapter, const auto &children, size_t f return std::make_pair(best_idx, best_diff); } +auto select_forced_strict_and_child_with_order(auto adapter, const auto &children, size_t first) { + auto est_until = [&](size_t limit)noexcept{ + double my_est = 1.0; + for (size_t i = 0; i < limit; ++i) { + my_est *= adapter.estimate(children[i]); + } + return my_est; + }; + double est = est_until(first); + double cost = 0.0; + size_t best_idx = 0; + size_t best_target = 0; + double best_diff = std::numeric_limits<double>::max(); + for (size_t idx = first; idx < children.size(); ++idx) { + auto child = FlowStats::from(adapter, children[idx]); + double child_abs_cost = est * child.cost; + double forced_cost = forced_strict_cost(child.estimate, child.strict_cost, est); + double my_diff = (forced_cost + child.estimate * cost) - (cost + child_abs_cost); + size_t target = first; + while (target > 0) { + size_t candidate = target - 1; + auto other = FlowStats::from(adapter, children[candidate]); + if (other.estimate < child.estimate) { + // do not move past someone with lower estimate + break; + } + if (!should_force_strict(other.estimate, other.cost, other.strict_cost, (est_until(candidate) * child.estimate))) { + // no not move past someone who will lose strictness + break; + } + target = candidate; + my_diff += (0.2 * child.estimate - 0.2 * other.estimate); + if (candidate == 0) { + // the first iterator produces its own in-flow + my_diff += (0.2 * child.estimate - 0.2 * other.estimate); + } + } + if (my_diff < best_diff) { + best_diff = my_diff; + best_idx = idx; + best_target = target; + } + cost += child_abs_cost; + est *= child.estimate; + } + return std::make_tuple(best_idx, best_target, best_diff); +} + } // flow template <typename FLOW> @@ -270,12 +323,8 @@ public: static void sort(auto adapter, auto &children, bool strict) { flow::sort<flow::MinAndCost>(adapter, children); if (strict && children.size() > 1) { - size_t idx = flow::select_strict_and_child(adapter, children); - auto the_one = std::move(children[idx]); - for (; idx > 0; --idx) { - children[idx] = std::move(children[idx-1]); - } - children[0] = std::move(the_one); + auto pos = children.begin() + flow::select_strict_and_child(adapter, children); + std::rotate(children.begin(), pos, pos + 1); } } static void sort(auto &children, bool strict) { diff --git a/searchlib/src/vespa/searchlib/queryeval/flow_tuning.h b/searchlib/src/vespa/searchlib/queryeval/flow_tuning.h index 53f2be88c1f..51e544b2e30 100644 --- a/searchlib/src/vespa/searchlib/queryeval/flow_tuning.h +++ b/searchlib/src/vespa/searchlib/queryeval/flow_tuning.h @@ -10,10 +10,6 @@ inline double heap_cost(double my_est, size_t num_children) { return my_est * std::log2(std::max(size_t(1),num_children)); } -inline double array_cost(double my_est, size_t num_children) { - return my_est * num_children; -} - /** * The following constants and formulas were derived after analyzing term search over attributes * (with and without fast-search) and disk index by using the iterator benchmark program: diff --git a/vespa-dependencies-enforcer/allowed-maven-dependencies.txt b/vespa-dependencies-enforcer/allowed-maven-dependencies.txt index 9ffde513481..fd7baf675b6 100644 --- a/vespa-dependencies-enforcer/allowed-maven-dependencies.txt +++ b/vespa-dependencies-enforcer/allowed-maven-dependencies.txt @@ -30,6 +30,7 @@ com.google.jimfs:jimfs:${jimfs.vespa.version} com.google.protobuf:protobuf-java:${protobuf.vespa.version} com.ibm.icu:icu4j:${icu4j.vespa.version} com.microsoft.onnxruntime:onnxruntime:${onnxruntime.vespa.version} +de.kherud:llama:${kherud.llama.vespa.version} com.sun.activation:javax.activation:1.2.0 com.sun.istack:istack-commons-runtime:4.1.2 com.sun.xml.bind:jaxb-core:${jaxb-core.vespa.version} @@ -131,12 +132,12 @@ org.assertj:assertj-core:${assertj.vespa.version} org.bouncycastle:bcpkix-jdk18on:${bouncycastle.vespa.version} org.bouncycastle:bcprov-jdk18on:${bouncycastle.vespa.version} org.bouncycastle:bcutil-jdk18on:${bouncycastle.vespa.version} -org.codehaus.plexus:plexus-archiver:4.8.0 +org.codehaus.plexus:plexus-archiver:${plexus-archiver.vespa.version} org.codehaus.plexus:plexus-classworlds:2.7.0 org.codehaus.plexus:plexus-component-annotations:2.1.0 org.codehaus.plexus:plexus-container-default:1.0-alpha-9-stable-1 org.codehaus.plexus:plexus-interpolation:${plexus-interpolation.vespa.version} -org.codehaus.plexus:plexus-io:${maven-enforcer-plugin.vespa.version} +org.codehaus.plexus:plexus-io:${plexus-io.vespa.version} org.codehaus.plexus:plexus-utils:${plexus-utils.vespa.version} org.eclipse.angus:angus-activation:${eclipse-angus.vespa.version} org.eclipse.collections:eclipse-collections-api:${eclipse-collections.vespa.version} diff --git a/vespa-feed-client/src/main/java/ai/vespa/feed/client/impl/GracePeriodCircuitBreaker.java b/vespa-feed-client/src/main/java/ai/vespa/feed/client/impl/GracePeriodCircuitBreaker.java index 73bdb65eefb..1ea2089c0eb 100644 --- a/vespa-feed-client/src/main/java/ai/vespa/feed/client/impl/GracePeriodCircuitBreaker.java +++ b/vespa-feed-client/src/main/java/ai/vespa/feed/client/impl/GracePeriodCircuitBreaker.java @@ -66,7 +66,7 @@ public class GracePeriodCircuitBreaker implements FeedClient.CircuitBreaker { public void success() { failingSinceMillis.set(NEVER); if ( ! open.get() && halfOpen.compareAndSet(true, false)) - log.log(FINE, "Circuit breaker is now closed"); + log.log(INFO, "Circuit breaker is now closed, after a request was successful"); } @Override diff --git a/vespa-feed-client/src/main/java/ai/vespa/feed/client/impl/StaticThrottler.java b/vespa-feed-client/src/main/java/ai/vespa/feed/client/impl/StaticThrottler.java index e26f4b83a1e..cc4e5edd135 100644 --- a/vespa-feed-client/src/main/java/ai/vespa/feed/client/impl/StaticThrottler.java +++ b/vespa-feed-client/src/main/java/ai/vespa/feed/client/impl/StaticThrottler.java @@ -21,7 +21,7 @@ public class StaticThrottler implements Throttler { private final AtomicLong targetX10; public StaticThrottler(FeedClientBuilderImpl builder) { - minInflight = 16L * builder.connectionsPerEndpoint * builder.endpoints.size(); + minInflight = 8L * builder.connectionsPerEndpoint * builder.endpoints.size(); maxInflight = 256 * minInflight; // 4096 max streams per connection on the server side. targetX10 = new AtomicLong(10 * maxInflight); // 10x the actual value to allow for smaller updates. } |