diff --git a/.github/workflows/code-checker.yaml b/.github/workflows/code-checker.yaml index 674a47bdd8..efe5c05320 100644 --- a/.github/workflows/code-checker.yaml +++ b/.github/workflows/code-checker.yaml @@ -110,4 +110,54 @@ jobs: mkdir -p /var/tmp/ccache fi brew install boost libomp ninja tbb ccache - make check-proto-product && make verifiers \ No newline at end of file + make check-proto-product && make verifiers + mingw64: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + include: + - name: Code Checker MinGW + os: windows-2019 + steps: + - name: Set git to use LF + run: | + git config --global core.autocrlf false + git config --global core.eol lf + - name: Checkout + uses: actions/checkout@v2 + - name: Cache go + uses: actions/cache@v2 + with: + path: | + %LocalAppData%\go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-go- + - name: Cache ccache + uses: actions/cache@v2 + with: + path: | + ${{ github.workspace }}/.ccache + key: ${{ runner.os }}-ccache-${{ hashFiles('internal/core/**') }} + restore-keys: ${{ runner.os }}-ccache- + - name: Configure Toolchain + uses: msys2/setup-msys2@v2 + with: + msystem: mingw64 + - name: Install Deps + shell: msys2 {0} + run: | + sh scripts/install_deps_msys.sh + - name: Code Check + shell: msys2 {0} + env: + CCACHE_COMPILERCHECK: content + CCACHE_COMPRESS: 1 + CCACHE_COMPRESSLEVEL: 5 + CCACHE_MAXSIZE: 2G + CCACHE_DIR: ${{ github.workspace }}/.ccache + run: | + mingw32-make verifiers build-go diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index e5ceba67b9..e8e10edeaf 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -92,4 +92,3 @@ jobs: files: ./go_coverage.txt,./lcov_output.info name: ubuntu-${{ matrix.ubuntu }}-unittests fail_ci_if_error: true - diff --git a/Makefile b/Makefile index 74e0c98476..9192b4ab3c 100644 --- a/Makefile +++ b/Makefile @@ -28,6 +28,10 @@ ifeq ($(OS),Darwin) # MacOS X @echo "MacOS system identified. Switching to customized gorocksdb fork..." @go mod edit -replace=github.com/tecbot/gorocksdb=github.com/soothing-rain/gorocksdb@v0.0.1 endif +ifeq ($(MSYSTEM), MINGW64) # MSYS + @echo "MSYS. Switching to customized gorocksdb fork..." + @go mod edit -replace=github.com/tecbot/gorocksdb=github.com/soothing-rain/gorocksdb@v0.0.1 +endif get-build-deps: @(env bash $(PWD)/scripts/install_deps.sh) diff --git a/cmd/milvus/milvus.go b/cmd/milvus/milvus.go index f231a4661f..2480ff018b 100644 --- a/cmd/milvus/milvus.go +++ b/cmd/milvus/milvus.go @@ -8,9 +8,11 @@ import ( syslog "log" "os" "path" + "runtime" "strings" "syscall" + "github.com/gofrs/flock" "github.com/milvus-io/milvus/cmd/roles" "github.com/milvus-io/milvus/internal/util/paramtable" "github.com/milvus-io/milvus/internal/util/typeutil" @@ -90,7 +92,7 @@ func getPidFileName(serverType string, alias string) string { return filename } -func createPidFile(w io.Writer, filename string, runtimeDir string) (*os.File, error) { +func createPidFile(w io.Writer, filename string, runtimeDir string) (*flock.Flock, error) { fileFullName := path.Join(runtimeDir, filename) fd, err := os.OpenFile(fileFullName, os.O_CREATE|os.O_RDWR, 0664) @@ -99,11 +101,7 @@ func createPidFile(w io.Writer, filename string, runtimeDir string) (*os.File, e } fmt.Fprintln(w, "open pid file:", fileFullName) - err = syscall.Flock(int(fd.Fd()), syscall.LOCK_EX|syscall.LOCK_NB) - if err != nil { - return nil, fmt.Errorf("file %s is locked, error = %w", filename, err) - } - fmt.Fprintln(w, "lock pid file:", fileFullName) + defer fd.Close() fd.Truncate(0) _, err = fd.WriteString(fmt.Sprintf("%d", os.Getpid())) @@ -111,16 +109,24 @@ func createPidFile(w io.Writer, filename string, runtimeDir string) (*os.File, e return nil, fmt.Errorf("file %s write fail, error = %w", filename, err) } - return fd, nil + lock := flock.New(fileFullName) + _, err = lock.TryLock() + if err != nil { + return nil, fmt.Errorf("file %s is locked, error = %w", filename, err) + } + + fmt.Fprintln(w, "lock pid file:", fileFullName) + return lock, nil } func closePidFile(fd *os.File) { fd.Close() } -func removePidFile(fd *os.File) { - syscall.Close(int(fd.Fd())) - os.Remove(fd.Name()) +func removePidFile(lock *flock.Flock) { + filename := lock.Path() + lock.Close() + os.Remove(filename) } func stopPid(filename string, runtimeDir string) error { @@ -182,6 +188,28 @@ func printUsage(w io.Writer, f *flag.Flag) { fmt.Fprint(w, s, "\n") } +// create runtime folder +func createRuntimeDir() string { + runtimeDir := "/run/milvus" + if runtime.GOOS == "windows" { + runtimeDir = "run" + if err := makeRuntimeDir(runtimeDir); err != nil { + fmt.Fprintf(os.Stderr, "Create runtime directory at %s failed\n", runtimeDir) + os.Exit(-1) + } + } else { + if err := makeRuntimeDir(runtimeDir); err != nil { + fmt.Fprintf(os.Stderr, "Set runtime dir at %s failed, set it to /tmp/milvus directory\n", runtimeDir) + runtimeDir = "/tmp/milvus" + if err = makeRuntimeDir(runtimeDir); err != nil { + fmt.Fprintf(os.Stderr, "Create runtime directory at %s failed\n", runtimeDir) + os.Exit(-1) + } + } + } + return runtimeDir +} + func RunMilvus(args []string) { if len(args) < 3 { _, _ = fmt.Fprint(os.Stderr, "usage: milvus [command] [server type] [flags]\n") @@ -283,36 +311,17 @@ func RunMilvus(args []string) { params.SetLogger(0) } - var runtimeDir string - // For embedded Milvus, runtime dir is always /run/milvus. - if serverType == typeutil.EmbeddedRole { - runtimeDir = "/tmp/milvus" - } else { - runtimeDir = "/run/milvus" - } - if err := makeRuntimeDir(runtimeDir); err != nil { - if serverType == typeutil.EmbeddedRole { - fmt.Fprintf(os.Stderr, "Create runtime directory at %s failed\n", runtimeDir) - os.Exit(-1) - } - fmt.Fprintf(os.Stderr, "Set runtime dir at %s failed, set it to /tmp/milvus directory\n", runtimeDir) - runtimeDir = "/tmp/milvus" - if err = makeRuntimeDir(runtimeDir); err != nil { - fmt.Fprintf(os.Stderr, "Create runtime directory at %s failed\n", runtimeDir) - os.Exit(-1) - } - } - + runtimeDir := createRuntimeDir() filename := getPidFileName(serverType, svrAlias) switch command { case "run": printBanner(flags.Output()) injectVariablesToEnv() - fd, err := createPidFile(flags.Output(), filename, runtimeDir) + lock, err := createPidFile(flags.Output(), filename, runtimeDir) if err != nil { panic(err) } - defer removePidFile(fd) + defer removePidFile(lock) role.Run(local, svrAlias) case "stop": if err := stopPid(filename, runtimeDir); err != nil { diff --git a/deployments/windows/cleanup_data.bat b/deployments/windows/cleanup_data.bat new file mode 100644 index 0000000000..742512a18b --- /dev/null +++ b/deployments/windows/cleanup_data.bat @@ -0,0 +1,4 @@ +cd /d %~dp0 + +rmdir /s /q default.etcd s3data var +del /q *.log \ No newline at end of file diff --git a/deployments/windows/run_etcd.bat b/deployments/windows/run_etcd.bat new file mode 100644 index 0000000000..9a2f0eb9e3 --- /dev/null +++ b/deployments/windows/run_etcd.bat @@ -0,0 +1,2 @@ +cd /d %~dp0 +bin\etcd.exe \ No newline at end of file diff --git a/deployments/windows/run_milvus.bat b/deployments/windows/run_milvus.bat new file mode 100644 index 0000000000..7bb36df4c6 --- /dev/null +++ b/deployments/windows/run_milvus.bat @@ -0,0 +1,2 @@ +cd /d %~dp0 +bin\milvus.exe run standalone \ No newline at end of file diff --git a/deployments/windows/run_minio.bat b/deployments/windows/run_minio.bat new file mode 100644 index 0000000000..0c4991ac8e --- /dev/null +++ b/deployments/windows/run_minio.bat @@ -0,0 +1,2 @@ +cd /d %~dp0 +bin\minio.exe server s3data \ No newline at end of file diff --git a/go.mod b/go.mod index d181f31360..097562422e 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 // indirect github.com/gin-gonic/gin v1.7.7 github.com/go-basic/ipv4 v1.0.0 + github.com/gofrs/flock v0.8.1 // indirect github.com/golang/mock v1.5.0 github.com/golang/protobuf v1.5.2 github.com/google/btree v1.0.1 diff --git a/go.sum b/go.sum index d6fc4fb9be..a1b76f1a11 100644 --- a/go.sum +++ b/go.sum @@ -198,6 +198,8 @@ github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+ github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= diff --git a/internal/core/CMakeLists.txt b/internal/core/CMakeLists.txt index 4cd9c4cb36..31773cedf8 100644 --- a/internal/core/CMakeLists.txt +++ b/internal/core/CMakeLists.txt @@ -54,6 +54,8 @@ if ( APPLE ) elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") message(STATUS "==============Linux Environment===============") set(LINUX TRUE) +elseif ( MSYS ) + message( STATUS "==============MSYS Environment===============" ) else () message(FATAL_ERROR "Unsupported platform!" ) endif () @@ -114,7 +116,7 @@ include( ThirdPartyPackages ) # **************************** Compiler arguments **************************** message( STATUS "Building Milvus CPU version" ) -if (LINUX) +if (LINUX OR MSYS) append_flags( CMAKE_CXX_FLAGS FLAGS "-fPIC" diff --git a/internal/core/src/indexbuilder/CMakeLists.txt b/internal/core/src/indexbuilder/CMakeLists.txt index 70d7533b35..01fcf2dc9d 100644 --- a/internal/core/src/indexbuilder/CMakeLists.txt +++ b/internal/core/src/indexbuilder/CMakeLists.txt @@ -22,7 +22,7 @@ add_library(milvus_indexbuilder SHARED find_library(TBB NAMES tbb) set(PLATFORM_LIBS dl) if (MSYS) -set(PLATFORM_LIBS ) +set(PLATFORM_LIBS -Wl,--allow-multiple-definition) endif () # link order matters diff --git a/internal/core/src/indexbuilder/index_c.cpp b/internal/core/src/indexbuilder/index_c.cpp index ab3ce135ba..b6d99d0e17 100644 --- a/internal/core/src/indexbuilder/index_c.cpp +++ b/internal/core/src/indexbuilder/index_c.cpp @@ -53,7 +53,7 @@ void DeleteIndex(CIndex index) { auto cIndex = (milvus::indexbuilder::IndexWrapper*)index; delete cIndex; -#ifndef __APPLE__ +#ifdef __linux__ malloc_trim(0); #endif } diff --git a/internal/core/src/log/Log.cpp b/internal/core/src/log/Log.cpp index 373f3744cd..800e201278 100644 --- a/internal/core/src/log/Log.cpp +++ b/internal/core/src/log/Log.cpp @@ -48,7 +48,7 @@ SetThreadName(const std::string& name) { // Note: the name cannot exceed 16 bytes #ifdef __APPLE__ pthread_setname_np(name.c_str()); -#elif __linux__ +#elif defined(__linux__) || defined(__MINGW64__) pthread_setname_np(pthread_self(), name.c_str()); #else #error "Unsupported SetThreadName"; diff --git a/internal/core/src/query/SearchBruteForce.cpp b/internal/core/src/query/SearchBruteForce.cpp index f9113b372d..efb29a71f9 100644 --- a/internal/core/src/query/SearchBruteForce.cpp +++ b/internal/core/src/query/SearchBruteForce.cpp @@ -15,7 +15,7 @@ #ifdef __APPLE__ #include "knowhere/index/vector_index/impl/bruteforce/BruteForce.h" #include "knowhere/common/Heap.h" -#elif __linux__ +#elif defined(__linux__) || defined(__MINGW64__) #include #include #else @@ -42,7 +42,7 @@ raw_search(MetricType metric_type, float* D, idx_t* labels, const BitsetView bitset) { -#ifdef __linux__ +#if defined(__linux__) || defined(__MINGW64__) using namespace faiss; // NOLINT if (metric_type == METRIC_Jaccard || metric_type == METRIC_Tanimoto) { float_maxheap_array_t res = {size_t(n), size_t(k), labels, D}; @@ -121,7 +121,7 @@ FloatSearchBruteForce(const dataset::SearchDataset& dataset, sub_qr.get_distances()}; knowhere::knn_inner_product_sse(query_data, chunk_data, dim, num_queries, size_per_chunk, &buf, bitset); } -#elif __linux__ +#elif defined(__linux__) || defined(__MINGW64__) if (metric_type == MetricType::METRIC_L2) { faiss::float_maxheap_array_t buf{(size_t)num_queries, (size_t)topk, sub_qr.get_ids(), sub_qr.get_distances()}; faiss::knn_L2sqr(query_data, chunk_data, dim, num_queries, size_per_chunk, &buf, bitset); diff --git a/internal/core/src/segcore/FieldIndexing.cpp b/internal/core/src/segcore/FieldIndexing.cpp index d704807ed2..e1554a9295 100644 --- a/internal/core/src/segcore/FieldIndexing.cpp +++ b/internal/core/src/segcore/FieldIndexing.cpp @@ -13,7 +13,7 @@ #include #include "common/SystemProperty.h" -#ifdef __linux__ +#if defined(__linux__) || defined(__MINGW64__) #include "knowhere/index/vector_index/IndexIVF.h" #endif #include "knowhere/index/vector_index/adapter/VectorAdapter.h" @@ -23,7 +23,7 @@ namespace milvus::segcore { void VectorFieldIndexing::BuildIndexRange(int64_t ack_beg, int64_t ack_end, const VectorBase* vec_base) { -#ifdef __linux__ +#if defined(__linux__) || defined(__MINGW64__) AssertInfo(field_meta_.get_data_type() == DataType::VECTOR_FLOAT, "Data type of vector field is not VECTOR_FLOAT"); auto dim = field_meta_.get_dim(); diff --git a/internal/core/src/segcore/collection_c.cpp b/internal/core/src/segcore/collection_c.cpp index 019e72daf6..b3bd13e7a3 100644 --- a/internal/core/src/segcore/collection_c.cpp +++ b/internal/core/src/segcore/collection_c.cpp @@ -28,7 +28,7 @@ void DeleteCollection(CCollection collection) { auto col = (milvus::segcore::Collection*)collection; delete col; -#ifndef __APPLE__ +#ifdef __linux__ malloc_trim(0); #endif } diff --git a/internal/core/thirdparty/knowhere/CMakeLists.txt b/internal/core/thirdparty/knowhere/CMakeLists.txt index 38f7391aa4..04f2f45826 100644 --- a/internal/core/thirdparty/knowhere/CMakeLists.txt +++ b/internal/core/thirdparty/knowhere/CMakeLists.txt @@ -21,6 +21,13 @@ else () "https://github.com/milvus-io/knowhere/archive/refs/tags/${KNOWHERE_VERSION}.tar.gz" ) endif () +if (MSYS) + # TODO(matrixji) replace with official release after `support windows` merged/tagged + # windows adaptation + milvus-io/knowhere@v1.0.1 + set (KNOWHERE_SOURCE_URL "https://github.com/matrixji/knowhere/archive/refs/tags/windows-int-20220310-p1.tar.gz") + set (KNOWHERE_SOURCE_MD5 "7a75cbaa68377f0c310e7f71bfd7becf") +endif (MSYS) + macro(build_knowhere) message(STATUS "Building knowhere-${KNOWHERE_VERSION} from source") set (KNOWHERE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) @@ -55,6 +62,7 @@ macro(build_knowhere) PROPERTIES IMPORTED_GLOBAL TRUE IMPORTED_LOCATION ${INSTALL_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}knowhere${CMAKE_SHARED_LIBRARY_SUFFIX} + IMPORTED_IMPLIB ${INSTALL_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}knowhere${CMAKE_SHARED_LIBRARY_SUFFIX}.a INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/${CMAKE_INSTALL_INCLUDEDIR}) add_dependencies(knowhere knowhere_ep) diff --git a/internal/datacoord/server.go b/internal/datacoord/server.go index 58acae3e9f..bbf620e687 100644 --- a/internal/datacoord/server.go +++ b/internal/datacoord/server.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "math/rand" + "os" "sync" "sync/atomic" "syscall" @@ -224,7 +225,9 @@ func (s *Server) Register() error { } // manually send signal to starter goroutine if s.session.TriggerKill { - syscall.Kill(syscall.Getpid(), syscall.SIGINT) + if p, err := os.FindProcess(os.Getpid()); err == nil { + p.Signal(syscall.SIGINT) + } } }) return nil @@ -628,7 +631,9 @@ func (s *Server) watchService(ctx context.Context) { logutil.Logger(s.ctx).Error("watch service channel closed", zap.Int64("serverID", s.session.ServerID)) go s.Stop() if s.session.TriggerKill { - syscall.Kill(syscall.Getpid(), syscall.SIGINT) + if p, err := os.FindProcess(os.Getpid()); err == nil { + p.Signal(syscall.SIGINT) + } } return } diff --git a/internal/datanode/data_node.go b/internal/datanode/data_node.go index 51498ba271..16410f46b2 100644 --- a/internal/datanode/data_node.go +++ b/internal/datanode/data_node.go @@ -25,6 +25,7 @@ import ( "fmt" "io" "math/rand" + "os" "path" "strconv" "strings" @@ -185,7 +186,9 @@ func (node *DataNode) Register() error { } // manually send signal to starter goroutine if node.session.TriggerKill { - syscall.Kill(syscall.Getpid(), syscall.SIGINT) + if p, err := os.FindProcess(os.Getpid()); err == nil { + p.Signal(syscall.SIGINT) + } } }) diff --git a/internal/indexcoord/index_coord.go b/internal/indexcoord/index_coord.go index f094679726..1779d55292 100644 --- a/internal/indexcoord/index_coord.go +++ b/internal/indexcoord/index_coord.go @@ -20,6 +20,7 @@ import ( "context" "errors" "math/rand" + "os" "sort" "strconv" "sync" @@ -134,7 +135,9 @@ func (i *IndexCoord) Register() error { } // manually send signal to starter goroutine if i.session.TriggerKill { - syscall.Kill(syscall.Getpid(), syscall.SIGINT) + if p, err := os.FindProcess(os.Getpid()); err == nil { + p.Signal(syscall.SIGINT) + } } }) return nil @@ -770,7 +773,9 @@ func (i *IndexCoord) watchNodeLoop() { log.Error("Session Watcher channel closed", zap.Int64("server id", i.session.ServerID)) go i.Stop() if i.session.TriggerKill { - syscall.Kill(syscall.Getpid(), syscall.SIGINT) + if p, err := os.FindProcess(os.Getpid()); err == nil { + p.Signal(syscall.SIGINT) + } } return } diff --git a/internal/indexnode/index.go b/internal/indexnode/index.go index ecfc90af86..6fbb2147e7 100644 --- a/internal/indexnode/index.go +++ b/internal/indexnode/index.go @@ -22,6 +22,7 @@ package indexnode #cgo darwin LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_common -lmilvus_indexbuilder -Wl,-rpath,"${SRCDIR}/../core/output/lib" #cgo linux LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_common -lmilvus_indexbuilder -Wl,-rpath=${SRCDIR}/../core/output/lib +#cgo windows LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_common -lmilvus_indexbuilder -Wl,-rpath=${SRCDIR}/../core/output/lib #include // free #include "segcore/collection_c.h" diff --git a/internal/indexnode/indexnode.go b/internal/indexnode/indexnode.go index d6727d6a63..978543299d 100644 --- a/internal/indexnode/indexnode.go +++ b/internal/indexnode/indexnode.go @@ -22,6 +22,7 @@ package indexnode #cgo darwin LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_indexbuilder -Wl,-rpath,"${SRCDIR}/../core/output/lib" #cgo linux LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_indexbuilder -Wl,-rpath=${SRCDIR}/../core/output/lib +#cgo windows LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_indexbuilder -Wl,-rpath=${SRCDIR}/../core/output/lib #include #include "indexbuilder/init_c.h" @@ -33,6 +34,7 @@ import ( "errors" "io" "math/rand" + "os" "strconv" "sync" "sync/atomic" @@ -131,7 +133,9 @@ func (i *IndexNode) Register() error { } // manually send signal to starter goroutine if i.session.TriggerKill { - syscall.Kill(syscall.Getpid(), syscall.SIGINT) + if p, err := os.FindProcess(os.Getpid()); err == nil { + p.Signal(syscall.SIGINT) + } } }) return nil diff --git a/internal/proxy/proxy.go b/internal/proxy/proxy.go index 7083cc4721..aa91a773c7 100644 --- a/internal/proxy/proxy.go +++ b/internal/proxy/proxy.go @@ -20,6 +20,7 @@ import ( "context" "errors" "math/rand" + "os" "strconv" "sync" "sync/atomic" @@ -126,7 +127,9 @@ func (node *Proxy) Register() error { log.Fatal("failed to stop server", zap.Error(err)) } if node.session.TriggerKill { - syscall.Kill(syscall.Getpid(), syscall.SIGINT) + if p, err := os.FindProcess(os.Getpid()); err == nil { + p.Signal(syscall.SIGINT) + } } }) // TODO Reset the logger diff --git a/internal/querycoord/query_coord.go b/internal/querycoord/query_coord.go index aeebce6bfa..f848a308e9 100644 --- a/internal/querycoord/query_coord.go +++ b/internal/querycoord/query_coord.go @@ -22,6 +22,7 @@ import ( "fmt" "math" "math/rand" + "os" "sort" "strconv" "sync" @@ -110,7 +111,9 @@ func (qc *QueryCoord) Register() error { } // manually send signal to starter goroutine if qc.session.TriggerKill { - syscall.Kill(syscall.Getpid(), syscall.SIGINT) + if p, err := os.FindProcess(os.Getpid()); err == nil { + p.Signal(syscall.SIGINT) + } } }) return nil @@ -383,7 +386,9 @@ func (qc *QueryCoord) handleNodeEvent(ctx context.Context) { log.Error("Session Watcher channel closed", zap.Int64("server id", qc.session.ServerID)) go qc.Stop() if qc.session.TriggerKill { - syscall.Kill(syscall.Getpid(), syscall.SIGINT) + if p, err := os.FindProcess(os.Getpid()); err == nil { + p.Signal(syscall.SIGINT) + } } return } diff --git a/internal/querynode/collection.go b/internal/querynode/collection.go index 48c5199b79..468f416736 100644 --- a/internal/querynode/collection.go +++ b/internal/querynode/collection.go @@ -22,6 +22,7 @@ package querynode #cgo darwin LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_segcore -Wl,-rpath,"${SRCDIR}/../core/output/lib" #cgo linux LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_segcore -Wl,-rpath=${SRCDIR}/../core/output/lib +#cgo windows LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_segcore -Wl,-rpath=${SRCDIR}/../core/output/lib #include "segcore/collection_c.h" #include "segcore/segment_c.h" diff --git a/internal/querynode/load_index_info.go b/internal/querynode/load_index_info.go index 8fe5dad049..411587b51a 100644 --- a/internal/querynode/load_index_info.go +++ b/internal/querynode/load_index_info.go @@ -20,6 +20,7 @@ package querynode #cgo CFLAGS: -I${SRCDIR}/../core/output/include #cgo darwin LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_common -lmilvus_segcore -Wl,-rpath,"${SRCDIR}/../core/output/lib" #cgo linux LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_common -lmilvus_segcore -Wl,-rpath=${SRCDIR}/../core/output/lib +#cgo windows LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_common -lmilvus_segcore -Wl,-rpath=${SRCDIR}/../core/output/lib #include "segcore/load_index_c.h" #include "common/vector_index_c.h" diff --git a/internal/querynode/plan.go b/internal/querynode/plan.go index 6aceea7624..c7f0db213c 100644 --- a/internal/querynode/plan.go +++ b/internal/querynode/plan.go @@ -20,6 +20,7 @@ package querynode #cgo CFLAGS: -I${SRCDIR}/../core/output/include #cgo darwin LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_segcore -Wl,-rpath,"${SRCDIR}/../core/output/lib" #cgo linux LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_segcore -Wl,-rpath=${SRCDIR}/../core/output/lib +#cgo windows LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_segcore -Wl,-rpath=${SRCDIR}/../core/output/lib #include "segcore/collection_c.h" #include "segcore/segment_c.h" diff --git a/internal/querynode/query_node.go b/internal/querynode/query_node.go index 6c7d2165b4..184f11882b 100644 --- a/internal/querynode/query_node.go +++ b/internal/querynode/query_node.go @@ -22,6 +22,7 @@ package querynode #cgo darwin LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_segcore -Wl,-rpath,"${SRCDIR}/../core/output/lib" #cgo linux LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_segcore -Wl,-rpath=${SRCDIR}/../core/output/lib +#cgo windows LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_segcore -Wl,-rpath=${SRCDIR}/../core/output/lib #include "segcore/collection_c.h" #include "segcore/segment_c.h" @@ -34,6 +35,7 @@ import ( "context" "errors" "fmt" + "os" "path/filepath" "strconv" "sync" @@ -156,7 +158,9 @@ func (node *QueryNode) Register() error { } // manually send signal to starter goroutine if node.session.TriggerKill { - syscall.Kill(syscall.Getpid(), syscall.SIGINT) + if p, err := os.FindProcess(os.Getpid()); err == nil { + p.Signal(syscall.SIGINT) + } } }) @@ -222,7 +226,9 @@ func (node *QueryNode) watchService(ctx context.Context) { // need to call stop in separate goroutine go node.Stop() if node.session.TriggerKill { - syscall.Kill(syscall.Getpid(), syscall.SIGINT) + if p, err := os.FindProcess(os.Getpid()); err == nil { + p.Signal(syscall.SIGINT) + } } return } diff --git a/internal/querynode/segment.go b/internal/querynode/segment.go index 5800efae9b..5ea68e7ae7 100644 --- a/internal/querynode/segment.go +++ b/internal/querynode/segment.go @@ -21,6 +21,7 @@ package querynode #cgo darwin LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_segcore -Wl,-rpath,"${SRCDIR}/../core/output/lib" #cgo linux LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_segcore -Wl,-rpath=${SRCDIR}/../core/output/lib +#cgo windows LDFLAGS: -L${SRCDIR}/../core/output/lib -lmilvus_segcore -Wl,-rpath=${SRCDIR}/../core/output/lib #include "segcore/collection_c.h" #include "segcore/plan_c.h" diff --git a/internal/rootcoord/root_coord.go b/internal/rootcoord/root_coord.go index 5f9bcb5928..42a227e73c 100644 --- a/internal/rootcoord/root_coord.go +++ b/internal/rootcoord/root_coord.go @@ -21,6 +21,7 @@ import ( "encoding/json" "fmt" "math/rand" + "os" "strconv" "strings" "sync" @@ -926,7 +927,9 @@ func (c *Core) Register() error { } // manually send signal to starter goroutine if c.session.TriggerKill { - syscall.Kill(syscall.Getpid(), syscall.SIGINT) + if p, err := os.FindProcess(os.Getpid()); err == nil { + p.Signal(syscall.SIGINT) + } } }) diff --git a/internal/storage/cwrapper/CMakeLists.txt b/internal/storage/cwrapper/CMakeLists.txt index 00c5cd59dd..1fb547e7b0 100644 --- a/internal/storage/cwrapper/CMakeLists.txt +++ b/internal/storage/cwrapper/CMakeLists.txt @@ -54,7 +54,6 @@ macro( build_arrow ) "-DARROW_TEST_MEMCHECK=OFF" "-DARROW_BUILD_BENCHMARKS=OFF" "-DARROW_CUDA=OFF" - "-DARROW_JEMALLOC=ON" "-DARROW_PYTHON=OFF" "-DARROW_WITH_RE2=OFF" "-DARROW_BUILD_UTILITIES=OFF" @@ -67,6 +66,11 @@ macro( build_arrow ) "-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}" "-DCMAKE_INCLUDE_PATH=${Boost_INCLUDE_DIRS}" ) + if (WIN32) + set( ARROW_CMAKE_ARGS ${ARROW_CMAKE_ARGS} "-DARROW_JEMALLOC=OFF" ) + else () + set( ARROW_CMAKE_ARGS ${ARROW_CMAKE_ARGS} "-DARROW_JEMALLOC=ON" ) + endif () ExternalProject_Add( arrow-ep @@ -115,10 +119,10 @@ macro( build_arrow ) endmacro() if (MSYS) - message("Using system arrow in msys") -else () + message(STATUS "Using arrow form system") +else (MSYS) build_arrow() -endif () +endif (MSYS) add_library(wrapper STATIC) target_sources(wrapper PUBLIC ParquetWrapper.cpp PayloadStream.cpp) diff --git a/internal/storage/payload.go b/internal/storage/payload.go index 0bb55e0b86..e1b5e69478 100644 --- a/internal/storage/payload.go +++ b/internal/storage/payload.go @@ -19,7 +19,9 @@ package storage /* #cgo CFLAGS: -I${SRCDIR}/cwrapper -#cgo LDFLAGS: -L${SRCDIR}/cwrapper/output/lib -L${SRCDIR}/cwrapper/output/lib64 -lwrapper -lparquet -larrow -larrow_bundled_dependencies -lstdc++ -lm +#cgo linux LDFLAGS: -L${SRCDIR}/cwrapper/output/lib -L${SRCDIR}/cwrapper/output/lib64 -lwrapper -lparquet -larrow -larrow_bundled_dependencies -lstdc++ -lm +#cgo darwin LDFLAGS: -L${SRCDIR}/cwrapper/output/lib -lwrapper -lparquet -larrow -larrow_bundled_dependencies -lstdc++ -lm +#cgo windows LDFLAGS: -L${SRCDIR}/cwrapper/output/lib -lwrapper -lparquet -larrow -lstdc++ #include #include "ParquetWrapper.h" */ diff --git a/internal/storage/print_binlog.go b/internal/storage/print_binlog.go index 0f72a3546a..98596a6be0 100644 --- a/internal/storage/print_binlog.go +++ b/internal/storage/print_binlog.go @@ -21,7 +21,8 @@ import ( "errors" "fmt" "os" - "syscall" + + "golang.org/x/exp/mmap" "github.com/golang/protobuf/proto" "github.com/milvus-io/milvus/internal/proto/internalpb" @@ -54,13 +55,14 @@ func printBinlogFile(filename string) error { fmt.Printf("file size = %d\n", fileInfo.Size()) - b, err := syscall.Mmap(int(fd.Fd()), 0, int(fileInfo.Size()), syscall.PROT_READ, syscall.MAP_SHARED) + at, err := mmap.Open(filename) if err != nil { return nil } - defer syscall.Munmap(b) + defer at.Close() - fmt.Printf("buf size = %d\n", len(b)) + b := make([]byte, fileInfo.Size()) + at.ReadAt(b, 0) r, err := NewBinlogReader(b) if err != nil { diff --git a/internal/util/cgoconverter/test_utils.go b/internal/util/cgoconverter/test_utils.go index 86022423e0..ed7f251fc2 100644 --- a/internal/util/cgoconverter/test_utils.go +++ b/internal/util/cgoconverter/test_utils.go @@ -12,8 +12,8 @@ func copyToCBytes(data []byte) unsafe.Pointer { } func mallocCBytes(v byte, len int) unsafe.Pointer { - p := C.malloc(C.ulong(len)) - C.memset(p, C.int(v), C.ulong(len)) + p := C.malloc(C.size_t(len)) + C.memset(p, C.int(v), C.size_t(len)) return p } diff --git a/scripts/core_build.sh b/scripts/core_build.sh index a544e76c62..b443c23ff4 100755 --- a/scripts/core_build.sh +++ b/scripts/core_build.sh @@ -136,6 +136,26 @@ if [[ ! -d ${BUILD_OUTPUT_DIR} ]]; then mkdir ${BUILD_OUTPUT_DIR} fi +CMAKE_GENERATOR="Unix Makefiles" + +# MSYS system +if [ "$MSYSTEM" == "MINGW64" ] ; then + BUILD_COVERAGE=OFF + PROFILING=OFF + GPU_VERSION=OFF + WITH_PROMETHEUS=OFF + CUDA_ARCH=OFF + + # extra default cmake args for msys + CMAKE_GENERATOR="MSYS Makefiles" + + # clang tools path + export CLANG_TOOLS_PATH=/mingw64/bin + + # using system blas + export OpenBLAS_HOME="$(cygpath -w /mingw64)" +fi + pushd ${BUILD_OUTPUT_DIR} # Remove make cache since build.sh -l use default variables @@ -164,6 +184,7 @@ esac CMAKE_CMD="cmake \ +${CMAKE_EXTRA_ARGS} \ -DBUILD_UNIT_TEST=${BUILD_UNITTEST} \ -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ @@ -178,8 +199,9 @@ CMAKE_CMD="cmake \ -DCUSTOM_THIRDPARTY_DOWNLOAD_PATH=${CUSTOM_THIRDPARTY_PATH} \ -DEMBEDDED_MILVUS=${EMBEDDED_MILVUS} \ ${CPP_SRC_DIR}" + echo ${CMAKE_CMD} -${CMAKE_CMD} +${CMAKE_CMD} -G "${CMAKE_GENERATOR}" if [[ ${RUN_CPPLINT} == "ON" ]]; then diff --git a/scripts/cwrapper_build.sh b/scripts/cwrapper_build.sh index d5bcfc7b56..24bc4af9e6 100755 --- a/scripts/cwrapper_build.sh +++ b/scripts/cwrapper_build.sh @@ -70,19 +70,28 @@ done echo "BUILD_TYPE: " $BUILD_TYPE echo "CUSTOM_THIRDPARTY_PATH: " $CUSTOM_THIRDPARTY_PATH + +# MSYS system +CMAKE_GENERATOR="Unix Makefiles" +if [ "$MSYSTEM" == "MINGW64" ] ; then + CMAKE_GENERATOR="MSYS Makefiles" +fi + pushd ${CMAKE_BUILD} CMAKE_CMD="cmake \ +${CMAKE_EXTRA_ARGS} \ -DCMAKE_INSTALL_PREFIX=${OUTPUT_LIB} \ -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ -DCUSTOM_THIRDPARTY_DOWNLOAD_PATH=${CUSTOM_THIRDPARTY_PATH} ${SRC_DIR}" -${CMAKE_CMD} +${CMAKE_CMD} -G "${CMAKE_GENERATOR}" echo ${CMAKE_CMD} if [[ ! ${jobs+1} ]]; then unameOut="$(uname -s)" case "${unameOut}" in Linux*) jobs=$(nproc);; + MINGW64*) jobs=$(nproc);; Darwin*) jobs=$(sysctl -n hw.physicalcpu);; *) echo "UNKNOWN:${unameOut}" ; exit 0; esac diff --git a/scripts/cwrapper_rocksdb_build.sh b/scripts/cwrapper_rocksdb_build.sh index b613f4fc57..aa1c7ef93c 100755 --- a/scripts/cwrapper_rocksdb_build.sh +++ b/scripts/cwrapper_rocksdb_build.sh @@ -70,9 +70,6 @@ CMAKE_CMD="cmake \ -DCMAKE_INSTALL_PREFIX=${OUTPUT_LIB} \ -DCUSTOM_THIRDPARTY_DOWNLOAD_PATH=${CUSTOM_THIRDPARTY_PATH} ${SRC_DIR}" -${CMAKE_CMD} -echo ${CMAKE_CMD} - unameOut="$(uname -s)" if [[ ! ${jobs+1} ]]; then case "${unameOut}" in @@ -82,7 +79,14 @@ if [[ ! ${jobs+1} ]]; then esac fi -make -j ${jobs} + +if [ "$MSYSTEM" == "MINGW64" ] ; then + echo Using system rocksdb +else + echo ${CMAKE_CMD} + ${CMAKE_CMD} + make -j ${jobs} +fi go env -w CGO_CFLAGS="-I${OUTPUT_LIB}/include" ldflags="" @@ -100,9 +104,15 @@ else esac fi +if [ "$MSYSTEM" == "MINGW64" ] ; then + ldflags="-L${OUTPUT_LIB}/lib -lrocksdb -lstdc++ -lm -lz -lshlwapi -lrpcrt4" +fi + + if [[ $(arch) == 'arm64' ]]; then go env -w GOARCH=arm64 fi go env -w CGO_LDFLAGS="$ldflags" && GO111MODULE=on + go get github.com/tecbot/gorocksdb diff --git a/scripts/install_deps_msys.sh b/scripts/install_deps_msys.sh new file mode 100644 index 0000000000..f4b38bfe66 --- /dev/null +++ b/scripts/install_deps_msys.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +set -e + +if [[ "${MSYSTEM}" != "MINGW64" ]] ; then + echo non MINGW64, exit. + exit 1 +fi + +pacman -Su --noconfirm --needed \ + git make tar dos2unix zip unzip patch \ + mingw-w64-x86_64-toolchain \ + mingw-w64-x86_64-make \ + mingw-w64-x86_64-ccache \ + mingw-w64-x86_64-cmake \ + mingw-w64-x86_64-go \ + mingw-w64-x86_64-boost \ + mingw-w64-x86_64-intel-tbb \ + mingw-w64-x86_64-openblas \ + mingw-w64-x86_64-clang \ + mingw-w64-x86_64-clang-tools-extra \ + mingw-w64-x86_64-python2 \ + mingw-w64-x86_64-diffutils \ + mingw-w64-x86_64-arrow \ + mingw-w64-x86_64-rocksdb + + +# dummy empty dl, TODO: remove later +touch a.c && \ + gcc -c a.c && \ + ar rc libdl.a a.o && \ + ranlib libdl.a && \ + cp -fr libdl.a /mingw64/lib && \ + rm -fr a.c a.o libdl.a + diff --git a/scripts/package_windows.sh b/scripts/package_windows.sh new file mode 100644 index 0000000000..102b665ce9 --- /dev/null +++ b/scripts/package_windows.sh @@ -0,0 +1,57 @@ +ETCD_VERSION=3.5.0 + +set -xe + +date_str="$(date +%Y%m%d)" +short_hash="$(git log -1 --pretty=%h)" + +version="${date_str}-${short_hash}" +target_filename="milvus-windows-${version}.zip" + +script_dir="$(cd $(dirname $0); pwd)" +repo_dir="$(dirname ${script_dir})" +bin_dir="${repo_dir}/bin" +package_dir="${repo_dir}/windows_package" + + +# prepare package dir +rm -fr ${package_dir} +mkdir -p ${package_dir} +cp -fr ${repo_dir}/deployments/windows ${package_dir}/milvus + +# resolve all dll for milvus.exe +cd ${bin_dir} +cp -fr milvus milvus.exe + +find ${repo_dir} -name \*.dll | xargs -I {} cp -frv {} . || : +for x in $(ldd milvus.exe | awk '{print $1}') ; do + if [ -f ${MINGW_PREFIX}/bin/$x ] ; then + cp -frv ${MINGW_PREFIX}/bin/$x . + fi +done + +# prepare package +cd ${package_dir} +mkdir -p milvus/{bin,configs,run} + +cp -frv ${bin_dir}/*.dll milvus/bin +cp -frv ${bin_dir}/*.exe milvus/bin + +# configs +cp -fr ${repo_dir}/configs/* milvus/configs/ + +# patch config /var -> var +sed s@/var/lib@var/lib@ -i milvus/configs/milvus.yaml + +# patch all bat with dos format +find -name \*.bat | xargs -I {} unix2dos {} + +# download minio +wget -q -O milvus/bin/minio.exe https://dl.min.io/server/minio/release/windows-amd64/minio.exe + +# download etcd +wget -q -O etcd.zip https://github.com/etcd-io/etcd/releases/download/v${ETCD_VERSION}/etcd-v${ETCD_VERSION}-windows-amd64.zip +unzip etcd.zip +find -name etcd.exe | xargs -I {} cp -frv {} milvus/bin + +zip -r ${target_filename} milvus