Principal Engineer for Accumulate

  • 6 Posts
  • 63 Comments
Joined 1 year ago
cake
Cake day: June 12th, 2023

help-circle


  • Sorry, I forgot about this. I’ve attached my full configuration at the end. The steps are:

    1. If the container is on a server, SSH to it or whatever.
    2. Execute docker exec --privileged -it container_name bash.
      • --privileged is required to make delve work. I don’t entirely remember why.
      • -it is something like --interactive and --terminal, it’s what you need to get a proper interactive shell.
      • container_name is the name of your container.
      • bash can also be sh or pwsh or whatever shell your container has (hopefully it has one).
    3. Launch delve dlv attach PID --headless --listen=:2345 --accept-multiclient --api-version=2.
      • PID is the ID of the process you want to debug. This should be 1 if you’re debugging the main process of the container.
      • --listen=:2345 says to listen on (TCP) port 2345 on all interfaces (0.0.0.0)
      • The other flags are the one that vscode-go expects.
    4. If the container is on a server, forward ports ssh ${USER}@${SERVER} -NL LOCAL:2345:REMOTE:2345.
      • LOCAL is the local IP to listen on, usually localhost. When a process connects to your local IP, it will be forwarded to the remote.
      • REMOTE is the remote IP to connect to, this should be the IP of your container. When a connection is forwarded from your local machine, this is where it is forwarded to. My containers are set up with --net host so I can use localhost as REMOTE but that’s not the default so you may have to use docker inspect to figure out your container’s IP.

    I also included the path substitution configs I use. I generally debug these by pausing the target, clicking on something in the stack trace, seeing what path it tries to load, then adjusting the substitute path so that it loads the correct file.

    {
      "name": "Attach to a docker container",
      // Get a shell in the container: `docker exec --privileged -it ${NAME} bash`
      // Launch delve:                 `dlv attach 1 --headless --listen=:2345 --accept-multiclient --api-version=2`
      // Forward the port (if remote): `ssh ${USER}@${SERVER} -NL localhost:2345:localhost:2345`
      // Then run this debug config
      "presentation": {
        "group": "99-Miscellaneous",
      },
      "type": "go",
      "request": "attach",
      "mode": "remote",
      "remotePath": "${workspaceFolder}",
      "port": 2345,
      "host": "127.0.0.1",
      "substitutePath": [
        // // Full paths (GitLab Docker build)
        // {
        //   "to": "/go/",
        //   "from": "${env:HOME}/go/", // <-- MODIFY THIS if you're not using the default GOPATH
        // },
        // {
        //   "to": "/root/",
        //   "from": "${workspaceFolder}",
        // },
        // Trimmed paths
        {
          "to": "gitlab.com/accumulatenetwork/accumulate/",
          "from": "${workspaceFolder}/",
        },
        {
          "to": "github.com/AccumulateNetwork/",
          "from": "${env:HOME}/go/pkg/mod/github.com/!accumulate!network/", // <-- MODIFY THIS if you're not using the default GOPATH
        },
        // {
        //   "to": "",
        //   "from": "${env:HOME}/go/pkg/mod/", // <-- MODIFY THIS if you're not using the default GOPATH
        // },
      ],
    }
    


  • Attaching to and debugging a process most certainly does work. I did it yesterday. Your issue is that Go doesn’t have any way of telling the process to pause until a debugger attaches. Which is frustrating but not the same issue.

    Specifically for debugging stdin, by far the easiest way to do that (in VSCode) is "console": "integratedTerminal". Another comment links a stack overflow answer that includes other options.


  • It’s not just about learning a language. Given two equivalent languages, writing a project using one or the other is always going to be less work and less of a maintenance burden than writing it using both. A competent manager will take that into account when deciding what tools to use. On top of that, learning a new language has a cost. Of course Rust and JavaScript are not equivalent, but which one is ‘better’ is highly subjective and dependent on how you measure ‘better’. So a manager needs to take that into account. But my fundamental point is that using two languages for a project adds overhead, and learning a language adds overhead, so unless cost (including time) is irrelevant, there must be a compelling reason to choose a dual-language solution* over a single-language solution, and to chose a solution that requires your devs to learn a new language over one that does not. Not to mention switching platforms has a massive cost if your project is already mature. Even if you’re creating a new project, if your team already knows JavaScript and doesn’t have any particular objection to Electron, there’s no compelling reason.

    If there is a good reason to learn a language then people will.

    Sure. Except in my experience interviewing candidates and from what I’ve seen online, there are a lot of developers out there who aren’t very good. I am not optimistic that the average developer will have an easy time learning a new language. If the “we” in “Is this the electron alternative we’ve been waiting for” is you and I, that’s not a problem. But if OP meant to suggest there will be a large-scale shift away from Electron, then the average developer is quite relevant.

    *As someone else pointed out, Dioxus is designed with the intent that you’ll right the frontend in Rust, so it’s not exactly dual-language like I thought.



  • I seriously doubt that a dual-language platform is ever going to supplant Electron. Electron has the major advantage that the entire app is written in one language. And according to Stack Overflow’s 2023 developer survey, 66% of devs use JavaScript, 45% use Python, 43% use TypeScript, and 12% use Rust. More devs use Java, C#, C++, PHP, and C than Rust. So 2/3 of developers wouldn’t have to learn a new language to use Electron, and only a small fraction of the remainder knows Rust.













  • I think the author’s primary point is, “Merging changes sucks, don’t make your users do that,” with a corollary: if your program loads configuration from a directory that is only populated by the user, there’s nothing to merge and thus never any merge conflicts. Case in point: /etc/polkit-1/rules.d. I can add whatever rules files I want in there and they’re never going to conflict when I update. If PolKit makes breaking changes to the format, it will log errors somewhere and I can look at those errors, look at my rules, and figure out how to fix them. That’s a hell of a lot easier than merging conflicting changes to code/configuration.


  • Additionally, switch performs extra sanity checks that checkout doesn’t, for example switch would abort operation if it would lead to loss of local changes.

    What checks? Under what situation does checkout lead to loss of changes? If I make changes and attempt to checkout a ref that would overwrite them, I get the following error:

    error: Your local changes to the following files would be overwritten by checkout:
            some/file
    Please commit your changes or stash them before you switch branches.
    Aborting
    

    To my knowledge it’s not possible to overwrite changes when switching branches/refs (git checkout <ref> without any other arguments or flags) so I guess what the author really means is, “If you use checkout incorrectly you can overwrite local changes.” As far as I can recall I’ve never accidentally git checkout <ref> <some/file> so I don’t see a reason to retrain my muscle memory. I do use git restore since it’s behavior is a lot more obvious than checkout/reset though sometimes I still use git checkout <ref> -- <some/file> because muscle memory.


    • Scenario: I’m in the middle of writing a new feature.
    • Boss, to me: “Shit broke. Go figure it out.”
    • Me, thinking: I’m in the middle of doing some complex work. If I commit/stash and close the open files, it will take a day for me to remember WTF I was doing.
    • Me: “Oh look, worktrees! I can leave my workspace intact with all the files open, pending changes, test results, terminal output, everything! And just create a new worktree to checkout the production version and debug! I’m saved!”

    Also setting up a worktree is really easy. git worktree add ../hotfix prod-branch && cd ../hotfix and get working. Though in reality it’s cd ../hotfix && git checkout prod-branch because I’ve never needed more than one secondary worktree.