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

feat(core): add support for cjson_encode_number_precision #11389

Closed
wants to merge 10 commits into from

Conversation

sabertobihwy
Copy link
Contributor

@sabertobihwy sabertobihwy commented Aug 11, 2023

This commit introduces a new configuration option called cjson_encode_number_precision. It specifies the precision used when encoding floating point numbers to JSON. The default value is 14, and the maximum value is 16. The commit also includes changes to various modules that make use of this configuration option.

Summary

Checklist

Full changelog

  • [Implement ...]

Issue reference

Fix FTI-5279

This commit introduces a new configuration option called `cjson_encode_number_precision`. It specifies the precision used when encoding floating point numbers to JSON. The default value is 14, and the maximum value is 16. The commit also includes changes to various modules that make use of this configuration option.
@CLAassistant
Copy link

CLAassistant commented Aug 11, 2023

CLA assistant check
All committers have signed the CLA.

@sabertobihwy
Copy link
Contributor Author

There are some points to discuss:

  • kong/pdk/vault.lua also has a local cjson = require(“cjson.safe”).new(), but it doesn’t use the cjson.encode function, so I didn’t handle it.
  • If a module calls require("cjson.safe").new(), then the cjson.encode_sparse_array(nil, nil, 2^15) in globalpatches.lua will become ineffective. Is this the expected behavior?

@sabertobihwy sabertobihwy marked this pull request as ready for review August 15, 2023 02:25
@flrgh
Copy link
Contributor

flrgh commented Aug 15, 2023

There are some points to discuss:

  • kong/pdk/vault.lua also has a local cjson = require(“cjson.safe”).new(), but it doesn’t use the cjson.encode function, so I didn’t handle it.

  • If a module calls require("cjson.safe").new(), then the cjson.encode_sparse_array(nil, nil, 2^15) in globalpatches.lua will become ineffective. Is this the expected behavior?

I have an idea. What about wrapping everything up in a kong/tools/json.lua module?

local _M = {}

local cjson = require("cjson")
local cjson_safe = require("cjson.safe")

local conf

_M.encode = cjson.encode
_M.decode = cjson.decode

_M.safe = {
  encode = cjson_safe.encode,
  decode = cjson_safe.decode,
}

function _M.configure(kong_conf)
  conf = kong_conf
  -- set encode_number_precision and other properties accordingly
end

function _M.new()
  local inst = cjson.new()
  if conf then
    -- set properties from conf accordingly
  end
  return inst
end

return _M

There's a chicken/egg condition with .new() and .configure(). It's mildly annoying to solve, but it can be done:

local instances = setmetatable({}, { __mode = "k" })

instances[cjson] = true
instances[cjson_safe] = true

-- repeat this for _M.safe.new, of course
function _M.new()
  local inst = cjson.new()
  if conf then
    -- set properties from conf accordingly
  end

  -- stash it in our registry
  instances[inst] = true

  return inst
end

function _M.configure(kong_conf)
  conf = kong_conf
  
  for inst in pairs(instances) do
    -- set encode_number_precision and other properties accordingly
  end
end

It's not 100% air-tight, but it should cover most cases. We could even expose this in the PDK at _G.kong.json or something of that nature. Existing code that uses cjson will just need s/cjson/kong.tools.json/.

@sabertobihwy
Copy link
Contributor Author

It's not 100% air-tight, but it should cover most cases. We could even expose this in the PDK at _G.kong.json or something of that nature. Existing code that uses cjson will just need s/cjson/kong.tools.json/.

Reasonable.

I think it need to open another PR to handle this.

kong.conf.default Outdated Show resolved Hide resolved
Copy link
Contributor

@StarlightIbuki StarlightIbuki left a comment

Choose a reason for hiding this comment

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

I feel it is more direct and intuitive to specify the default value instead of relying on the libraries' default behavior.

kong/conf_loader/init.lua Show resolved Hide resolved
kong/templates/kong_defaults.lua Outdated Show resolved Hide resolved
Copy link
Contributor

@ADD-SP ADD-SP left a comment

Choose a reason for hiding this comment

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

Is there any context for this PR? Which issues is this PR going to fix?

It pains me to add this configuration option like this, we don't want to add configuration options if we don't have to, because it would make configuring Kong more complicated.

@ms2008
Copy link
Contributor

ms2008 commented Aug 16, 2023

If a module calls require("cjson.safe").new(), then the cjson.encode_sparse_array(nil, nil, 2^15) in globalpatches.lua will become ineffective. Is this the expected behavior?

I think this issue should also be addressed in this PR to ensure that cjson behavior is consistent so as not to annoy users.

@sabertobihwy
Copy link
Contributor Author

Is there any context for this PR? Which issues is this PR going to fix?

background: https://konghq.atlassian.net/browse/FTI-5265?focusedCommentId=108202

Simply put, the default precision (14) cannot meet the needs of some users.

It pains me to add this configuration option like this, we don't want to add configuration options if we don't have to, because it would make configuring Kong more complicated.

I also don’t like adding configurations. Another way is to increase the default precision from 14 to 16, but this is a breaking change, so I didn’t do it initially.

@sabertobihwy
Copy link
Contributor Author

I think this issue should also be addressed in this PR to ensure that cjson behavior is consistent so as not to annoy users.

I think it would be better to complete this with another PR that matches the solution proposed by @flrgh , otherwise this PR will lose its original purpose and become bloated.

@sabertobihwy
Copy link
Contributor Author

I feel it is more direct and intuitive to specify the default value instead of relying on the libraries' default behavior.

Makes sense, should we declare a default precision of 14 in globalpatchers?

@StarlightIbuki
Copy link
Contributor

I feel it is more direct and intuitive to specify the default value instead of relying on the libraries' default behavior.

Makes sense, should we declare a default precision of 14 in globalpatchers?

We can make it the default value of the configuration and always pass the argument.

@sabertobihwy
Copy link
Contributor Author

We can make it the default value of the configuration and always pass the argument.

That is a breaking change, and I am concerned because not all users require 16-bit precision.

@sabertobihwy
Copy link
Contributor Author

So now there is a disagreement: whether to upgrade the default precision from 14 digits to 16 digits.
My opinion is no.
What is your opinion? cc @StarlightIbuki @ADD-SP @bungle

@StarlightIbuki
Copy link
Contributor

So now there is a disagreement: whether to upgrade the default precision from 14 digits to 16 digits. My opinion is no. What is your opinion? cc @StarlightIbuki @ADD-SP @bungle

I did not mean we need 16 as default. I mean 14 as the default but explicitly passed to the lib.

@vm-001
Copy link
Contributor

vm-001 commented Aug 29, 2023

Please add a changelog file

@kikito
Copy link
Member

kikito commented Sep 12, 2023

After considernig this in PR queue review, we are closing this. It is not a burning issue, it's controversial and the FTI ticket was resolved in a different way.

Please feel free to reopen.

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

Successfully merging this pull request may close these issues.

9 participants