Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions cmd/zoekt-webserver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"os"
"os/signal"
"path/filepath"
"runtime"
"strconv"
"strings"
"time"
Expand All @@ -45,7 +46,6 @@ import (
"github.com/uber/jaeger-client-go"
oteltrace "go.opentelemetry.io/otel/trace"
"go.uber.org/automaxprocs/maxprocs"
"golang.org/x/sys/unix"
"google.golang.org/grpc"

"github.com/sourcegraph/zoekt"
Expand Down Expand Up @@ -349,8 +349,8 @@ func addProxyHandler(mux *http.ServeMux, socket string) {
// times you will read the channel (used as buffer for signal.Notify).
func shutdownSignalChan(maxReads int) <-chan os.Signal {
c := make(chan os.Signal, maxReads)
signal.Notify(c, os.Interrupt) // terminal C-c and goreman
signal.Notify(c, unix.SIGTERM) // Kubernetes
signal.Notify(c, os.Interrupt) // terminal C-c and goreman
signal.Notify(c, PLATFORM_SIGTERM) // Kubernetes
return c
}

Expand Down Expand Up @@ -459,13 +459,28 @@ Possible remediations:
}
}

func diskUsage(path string) (*disk.UsageStat, error) {
duPath := path
if runtime.GOOS == "windows" {
duPath = filepath.VolumeName(duPath)
}
usage, err := disk.Usage(duPath)
if err != nil {
return nil, fmt.Errorf("diskUsage: %w", err)
}
return usage, err
}

func mustRegisterDiskMonitor(path string) {
prometheus.MustRegister(prometheus.NewGaugeFunc(prometheus.GaugeOpts{
Name: "src_disk_space_available_bytes",
Help: "Amount of free space disk space.",
ConstLabels: prometheus.Labels{"path": path},
}, func() float64 {
usage, _ := disk.Usage(path)
// I know there is no error handling here, and I don't like it
Copy link
Contributor

Choose a reason for hiding this comment

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

Tiny comment: these comments are unrelated to the change and not super useful (and also use "I" in an inaccurate way :))

// but there was no error handling in the previous version
// that used Statfs, either, so I'm assuming there's no need for it
usage, _ := diskUsage(path)
return float64(usage.Free)
}))

Expand All @@ -474,7 +489,10 @@ func mustRegisterDiskMonitor(path string) {
Help: "Amount of total disk space.",
ConstLabels: prometheus.Labels{"path": path},
}, func() float64 {
usage, _ := disk.Usage(path)
// I know there is no error handling here, and I don't like it
// but there was no error handling in the previous version
// that used Statfs, either, so I'm assuming there's no need for it
usage, _ := diskUsage(path)
return float64(usage.Total)
}))
}
Expand Down
9 changes: 9 additions & 0 deletions cmd/zoekt-webserver/main_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//go:build !windows

package main

import (
platform "golang.org/x/sys/unix"
)

const PLATFORM_SIGTERM = platform.SIGTERM
23 changes: 23 additions & 0 deletions cmd/zoekt-webserver/main_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2016 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
platform "golang.org/x/sys/windows"
)

const PLATFORM_SIGTERM = platform.SIGTERM

// Memory map metrics are provided in metrics_nonlinux.go
85 changes: 0 additions & 85 deletions cmd/zoekt-webserver/metrics.go

This file was deleted.

17 changes: 17 additions & 0 deletions cmd/zoekt-webserver/metrics_nonlinux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//go:build !linux

package main

import (
sglog "github.com/sourcegraph/log"
)

func mustRegisterMemoryMapMetrics(logger sglog.Logger) {
// The memory map metrics are collected via /proc, which
// is only available on linux-based operating systems.

// Other platforms do not have the same virtual memory statistics as Linux.
// For example, Windows does not have the concept of
// a count of memory maps, and a max number of memory maps
return
}
6 changes: 0 additions & 6 deletions index/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ import (
"github.com/dustin/go-humanize"
"github.com/go-enry/go-enry/v2"
"github.com/rs/xid"
"golang.org/x/sys/unix"

"maps"

Expand Down Expand Up @@ -1076,8 +1075,3 @@ func (e *deltaIndexOptionsMismatchError) Error() string {

// umask holds the Umask of the current process
var umask os.FileMode

func init() {
umask = os.FileMode(unix.Umask(0))
unix.Umask(int(umask))
}
14 changes: 14 additions & 0 deletions index/builder_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//go:build !windows

package index

import (
"os"

"golang.org/x/sys/unix"
)

func init() {
umask = os.FileMode(unix.Umask(0))
unix.Umask(int(umask))
}
22 changes: 22 additions & 0 deletions index/builder_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2018 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package index

// No OS-specific imports needed

func init() {
// no setting of file permissions on Windows
umask = 0
}
2 changes: 1 addition & 1 deletion index/indexfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build linux || darwin
//go:build !windows
Copy link
Contributor

Choose a reason for hiding this comment

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

Small comment, this file could be named indexfile_unix.go for consistency with the others.


package index

Expand Down
60 changes: 60 additions & 0 deletions index/indexfile_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2016 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package index

import (
"fmt"
"math"
"os"
)

// NewIndexFile returns a new index file. The index file takes
// ownership of the passed in file, and may close it.
func NewIndexFile(f *os.File) (IndexFile, error) {
return &indexFileFromOS{f}, nil
}

type indexFileFromOS struct {
f *os.File
}

func (f *indexFileFromOS) Read(off, sz uint32) ([]byte, error) {
r := make([]byte, sz)
Copy link
Contributor

@jtibshirani jtibshirani Apr 14, 2025

Choose a reason for hiding this comment

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

If we are really supporting Windows, we should use mmap here instead of direct reads. This provides the best experience, and I think it's an easier mental model for debugging/ support, to consistently use file mapping. Maybe we could re-introduce mmap-go, but just here for Windows? Or implement it directly, doesn't look too bad.

_, err := f.f.ReadAt(r, int64(off))
return r, err
}

func (f indexFileFromOS) Size() (uint32, error) {
fi, err := f.f.Stat()
if err != nil {
return 0, err
}

sz := fi.Size()

if sz >= math.MaxUint32 {
return 0, fmt.Errorf("overflow")
}

return uint32(sz), nil
}

func (f indexFileFromOS) Close() {
f.f.Close()
}

func (f indexFileFromOS) Name() string {
return f.f.Name()
}
20 changes: 20 additions & 0 deletions index/tombstones_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2018 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package index

func init() {
Copy link
Contributor

Choose a reason for hiding this comment

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

This part doesn't look right to me -- isn't this already handled in builder_windows.go?

By the way, I'm generally confused on why we are storing the system umask and manually applying it sometimes :)

// no setting of file permissions on Windows
umask = 0
}
Loading