Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add io/fs FS support #1374

Closed
wants to merge 4 commits into from
Closed

Add io/fs FS support #1374

wants to merge 4 commits into from

Conversation

Aoang
Copy link
Contributor

@Aoang Aoang commented Sep 13, 2022

No description provided.

@Aoang
Copy link
Contributor Author

Aoang commented Sep 13, 2022

RFC @erikdubbelboer

@erikdubbelboer
Copy link
Collaborator

I'm ok with dropping support for 1.15.

I would start without compress. Shouldn't the index page and byte-range work without any change since it's still just "files"? And I would add support for compression with in-memory cache after that.

@efectn
Copy link
Contributor

efectn commented Sep 18, 2022

I think you can implement fs.FS instead of embed.FS. It's more useful for general purpose.

@Aoang
Copy link
Contributor Author

Aoang commented Sep 18, 2022

I think you can implement fs.FS instead of embed.FS. It's more useful for general purpose.

LGMT. I'm doing and sharing my thoughts.

We first need to implement the Custom FS interface based on os.File to be compatible with the current API. Then complete fs.FS and embed.FS.

For some FS, we may need to self-implement io.ReadAt io.Seeker and more.

The challenge lies in how to elegantly implement the compression with in-memory or in-file cache. Oh, and zero alloc.

Of course, it may takes a while to complete it.

According to this line of thinking, compatibility existing APIs need a great care, and more tests need to be added.

Zero alloc and elegant code are like tongues and teeth, that sometimes collide.

@efectn
Copy link
Contributor

efectn commented Sep 18, 2022

I think you can implement fs.FS instead of embed.FS. It's more useful for general purpose.

LGMT. I'm doing and sharing my thoughts.

We first need to implement the Custom FS interface based on os.File to be compatible with the current API. Then complete fs.FS and embed.FS.

For some FS, we may need to self-implement io.ReadAt io.Seeker and more.

The challenge lies in how to elegantly implement the compression with in-memory or in-file cache. Oh, and zero alloc.

Of course, it may takes a while to complete it.

According to this line of thinking, compatibility existing APIs need a great care, and more tests need to be added.

Zero alloc and elegant code are like tongues and teeth, that sometimes collide.

Exactly agree. I'm also not sure about conpression with fs.Fs

@Aoang
Copy link
Contributor Author

Aoang commented Sep 20, 2022

I need some help.

https://github.com/valyala/fasthttp/blob/v1.40.0/fs.go#L822-L826

I don't quite understand why byte(0) needs to be handled separately. Does Linux, other systems or file systems have special handling? If handle exceptions, should handle all invisible characters, shouldn't you?

Going back to the source.
6a748e6#diff-a15ccbc05dcabeeea9949bb6a0cdb656ca2f12b96dfbcdd9fe4199ca65a3bcafR153-R157

I found that it already existed when it was created, can take a moment to answer it? @valyala

@kirillDanshin
Copy link
Collaborator

@Aoang null byte is a string delimiter. if we see it in the path, it means it was maliciously injected, and we need not to serve such request for security reasons. if we're talking Go in general, there's no realistic cases when a path would have a null byte, especially mid-string, as Go doesn't use null bytes to indicate the end of the string, instead it just stores the string length.

@Aoang
Copy link
Contributor Author

Aoang commented Sep 21, 2022

@Aoang
Copy link
Contributor Author

Aoang commented Oct 7, 2022

@erikdubbelboer
Copy link
Collaborator

I'm not sure I understand what the WaitGroup is for. But I think this happens when Add is called after Wait.

@Aoang
Copy link
Contributor Author

Aoang commented Oct 7, 2022

Test

  1. New Go File: wg.go
package testPoj

import (
	"sync"
	"time"
)

var wg = sync.WaitGroup{}

func R() {
	wg.Add(5)
	for i := 0; i < 5; i++ {
		run()
	}
	wg.Wait()
}

func run() {
	go func() {
		wg.Done()
		wg.Add(1)
		time.Sleep(time.Second)
		wg.Done()
	}()
}
  1. New Go File: wg_test.go
package testPoj

import (
	"testing"
)

func TestR(t *testing.T) {
	R()
}
  1. Run go test -v -race ./...
  2. Output:
➜  go test -v -race ./...
=== RUN   TestR
--- PASS: TestR (1.01s)
PASS
ok      testPoj 2.053s

Could this test be inaccurate? I‘ll try again tomorrow.

@erikdubbelboer
Copy link
Collaborator

What if you have multiple goroutines calling wg.Wait()? I can't imagine WaitGroup has any bugs in it.

@Aoang
Copy link
Contributor Author

Aoang commented Oct 13, 2022

Hi, in the implementation process, the package in internal depends on compress, so I copied a copy in internal/pool/compress.

There are so many exposed methods and variables in compress that it is not appropriate to put it in internal?

Should create a compress package like stackless?

> tree
.
├── allocation_test.go
├── coarseTime.go
├── coarseTime_test.go
├── compress [new package]
│   ├── compress.go
│   └── compress_test.go
├── compress.go [for compatibility, and marked as deprecated]
...

@erikdubbelboer
Copy link
Collaborator

Is there so much code that an internal package is really needed? I was hoping it would all fit into something like fs_embed.go in the root.

@Aoang
Copy link
Contributor Author

Aoang commented Oct 14, 2022

I don't think it is necessary, but there are too many duplicate names, such as io.FS and embed.FS.

I think it would be a lot easier to add embed.FS and io.FS functionality without making too many changes to the original code. You can copy a fsFSHandler and change the cache to a memory cache. Then, copy the code for the other logic and make some minor modifications to complete it.

Do you think this is better?

@erikdubbelboer
Copy link
Collaborator

Hard to judge without diving deep into it.

Isn't it possible to add an embed.FS to fasthttp.FS and use that to list dirs and open files if provided. For caching you then just do that in memory. Then compress etc can stay exactly the same.

What do you mean with io.FS?

@Aoang Aoang changed the title [WIP] Add embed fs Add io/fs FS support Oct 17, 2022
@Aoang Aoang marked this pull request as ready for review October 17, 2022 08:03
@Aoang
Copy link
Contributor Author

Aoang commented Oct 17, 2022

To be reviewed, I'll add comments.

@Aoang
Copy link
Contributor Author

Aoang commented Nov 1, 2022

No progress? close it

@Aoang Aoang closed this Nov 1, 2022
@efectn
Copy link
Contributor

efectn commented Nov 1, 2022

Why to close it? I think this would be great feature

@byene0923
Copy link
Contributor

why close?need some help?

@piyongcai
Copy link

没有进展?关闭它

@Aoang Why Close?

@Aoang
Copy link
Contributor Author

Aoang commented Jan 31, 2023

If you're interested in continuing this work, this patch might help. Based on it, then also need to add ByteRange support, maybe more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants