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

Trilogy.connect not working in Staging and Production environments. #149

Open
joshuapinter opened this issue Jan 23, 2024 · 8 comments · May be fixed by #151
Open

Trilogy.connect not working in Staging and Production environments. #149

joshuapinter opened this issue Jan 23, 2024 · 8 comments · May be fixed by #151

Comments

@joshuapinter
Copy link

In Staging and Production

config = Rails.configuration.database_configuration[ Rails.env ]
connection = Trilogy.new( config )
#=> .../trilogy-2.6.1/lib/trilogy.rb:18:in `_connect': No such file or directory - trilogy_connect - unable to connect to /tmp/mysql.sock (Trilogy::SyscallError::ENOENT)

In Development

config = Rails.configuration.database_configuration[ Rails.env ]
connection = Trilogy.new( config )
#=> <Trilogy:0x000000013a9de1e0

The configs between the environments are similar with just different database, username, password and host values.

Moreover, the actual Rails application (i.e. ActiveRecord) works just fine in all environments using Trilogy.

Any thoughts on this?

Thanks!

@bensheldon
Copy link
Contributor

Is your production database available via a socket file on that same host? unable to connect to /tmp/mysql.sock (Trilogy::SyscallError::ENOENT)

It looks like your configuration may still have Trilogy connecting via a file-based socket rather than remotely over the network and/or port 3306.

@joshuapinter
Copy link
Author

joshuapinter commented Jan 23, 2024

Thanks for the reply @bensheldon.

I don't think that's it because the actual app works just fine. As an example here is my staging environment config:

staging:
  database:  redacted
  username:  redacted
  password:  redacted
  adapter:   trilogy
  host:      redacted
  port:      3306

Is there something special with Trilogy.connect that we need to do to force it to use the host and port instead of a socket file?

@joshuapinter
Copy link
Author

Okay, I narrowed it down a bit. It looks like the config Hash is being completely ignored when passed to Trilogy.new, which looks like it is expecting named parameters.

That explains why it works in Development, because in Development, you don't need to pass the config and it'll still connect:

config = Rails.configuration.database_configuration[ Rails.env ]
Trilogy.new( config )
#=> <Trilogy:0x000000013a9de1e0
Trilogy.new
=> #<Trilogy:0x0000000139ef01e8

If I supply the named parameters manually it works:

Trilogy.new( host: redacted, port: 3306, username: redacted, password: redacted )
=> #<Trilogy:0x00007f676bbf79d8

I tried using splat (**) to convert the config to named parameters but that doesn't seem to work:

Trilogy.new( **config )
.../trilogy-2.6.1/lib/trilogy.rb:18:in `_connect': No such file or directory - trilogy_connect - unable to connect to /tmp/mysql.sock (Trilogy::SyscallError::ENOENT)

Any idea how to pass the config Hash to Trilogy.new?

@joshuapinter
Copy link
Author

Okay, figured it out. config is by default set with keys that are Strings wherease Trilogy.new is expecting Symbols.

This ended up working:

Trilogy.new( config.symbolize_keys )
#=> #<Trilogy:0x00007f676ba2a790

Is this something you can or want to handle in the library itself so it treats Strings and Symbols the same in the initialization config?

@bensheldon
Copy link
Contributor

bensheldon commented Jan 23, 2024

Oh! Nice find! I'd like that configuration to be more permissive and less surprising. It looks like we're already duping the connection options during initialization, so maybe that could do the symbolize keys too (with some slight reordering):

def initialize(options = {})
options[:port] = options[:port].to_i if options[:port]
mysql_encoding = options[:encoding] || "utf8mb4"
encoding = Trilogy::Encoding.find(mysql_encoding)
charset = Trilogy::Encoding.charset(mysql_encoding)
@connection_options = options
@connected_host = nil
_connect(encoding, charset, options)
end
def connection_options
@connection_options.dup.freeze
end

Edit: I misunderstood what we're doing with #connection_options. I think doing a symbolize_keys or equivalent still would be ok.

@joshuapinter
Copy link
Author

Yup, I would just symbolize the keys for options right at the start. Because this is just ruby I don't think we can use rails methods so I think options.transform_keys(&:to_sym) should do the trick.

Do you want to handle it or do you want me to submit a PR?

@bensheldon
Copy link
Contributor

@joshuapinter if you could submit a PR, I can take it from there 👍🏻

@joshuapinter
Copy link
Author

joshuapinter commented Jan 23, 2024

@bensheldon There ya go! #151

Thanks.

@joshuapinter joshuapinter linked a pull request Jan 24, 2024 that will close this issue
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 a pull request may close this issue.

2 participants