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

Nulls at SymbolSet #91

Open
kirillsinyuk opened this issue Feb 17, 2024 · 5 comments
Open

Nulls at SymbolSet #91

kirillsinyuk opened this issue Feb 17, 2024 · 5 comments
Assignees
Labels
bug Something isn't working
Milestone

Comments

@kirillsinyuk
Copy link

Describe the bug
I tried to generate lots of random phone numbers locally and at one point noticed nulls in generated strings

To Reproduce
Unfortunately, I can't tell the exact way to reproduce, after restart it came back to normal and I couldn't catch it again

Screenshots
RgxGen props in debug:
SCR-20240217-knia

Environment (please complete the following information):

  • OS: macOS
  • JDK/JRE version: 17
  • RgxGen Version: 1.4
@kirillsinyuk kirillsinyuk added the bug Something isn't working label Feb 17, 2024
@curious-odd-man
Copy link
Owner

curious-odd-man commented Feb 17, 2024

Hello!

The screenshot you provided indeed looks wierd:
image

I just have run a test:

    @Test
    public void bug91_nullsReturnedSometimes() {
        String pattern = "7\\d{10}";
        for (int i = 0; i < 1000000; i++) {
            RgxGen rgxGen = new RgxGen(pattern);
            Node node = rgxGen.getaNode();
            Sequence sequence = (Sequence) node;
            Repeat repeat = (Repeat) sequence.getNodes()[1];
            SymbolSet symbolSet = (SymbolSet) repeat.getNode();
            for (Character symbol : symbolSet.getSymbols()) {
                if (symbol == null) {
                    System.out.println("ERROR");
                }
            }
        }
    }

Which did not print a single error.

I have also dived into code to see if anything could cause such a behavior

The array of characters is created like this:

    Character[] getDigits() {
        if (aDigits == null) {
            aDigits = IntStream.rangeClosed('0', '9')
                               .mapToObj(i -> (char) i)
                               .toArray(Character[]::new);
        }

        return aDigits;
    }

And i don't see how those extra nulls could get in there.
image

Maybe you could run test on your machine to see if you get any errors.

@kirillsinyuk
Copy link
Author

kirillsinyuk commented Feb 19, 2024

I have a hypothesis.
It seems that RgxGen is not thread-safe and I tried to use it from several threads. This explains why I can't reproduce it easily.
So, generally, it's not the problem of this lib but the problem of my usage of it)
You can close the issue if you have no plans to work towards thread-safety.
And thanks for response.

@Avinm
Copy link

Avinm commented Apr 25, 2024

Hi @curious-odd-man,
Just experienced the same and found this issue. If you have no plans to make this thread safe, would you be able to call this out as non-ThreadSafe in the javadoc?

@curious-odd-man
Copy link
Owner

Hi @Avinm!

Thanks for reporting this. May I ask you to give me more details?
For example the pattern that you have used and maybe code example? Or, if you are working on open source project, you could share a link to a branch?

Additionally, could you please try out latest version 2.0 and confirm if the issue is still reproducible?

So far I wasn't able to reproduce this myself, but I will make a note in docs to highlight possible multithreading issues.

@Avinm
Copy link

Avinm commented Apr 25, 2024

@curious-odd-man :
I doubt the pattern has any bearing on this, so I used the same pattern as @kirillsinyuk .
I see a (mutable?) variable private final Node aNode; when looking through RgxGen class which doesn't look very thread safe:

@Test
@SneakyThrows
public void bug91_nullsReturnedSometimes() {
    String pattern = "7\\d{10}";
    val rgxGen = new RgxGen(pattern);
    val pool = Executors.newFixedThreadPool(64);
    val wrongStrings = pool.submit(() ->
        IntStream.range(0, 1000000)
                 .parallel()
                 .mapToObj(i -> rgxGen.generate())
                 .filter(s -> s.contains("null"))
                 .collect(Collectors.toList())
    ).get();
    assertEquals(Collections.emptyList(), wrongStrings);
}

image

@curious-odd-man curious-odd-man added this to the Version 2.1 milestone Apr 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants