Class: Synthra::Generator::FakerAdapter

Inherits:
Object
  • Object
show all
Defined in:
lib/synthra/generator/faker_adapter.rb

Overview

Note:

Performance Consideration: All FakerAdapter instances share a single class-level mutex to synchronize access to Faker's global state. Under very high concurrency (100+ threads), Faker calls will serialize through this mutex, creating a potential bottleneck. This is an acceptable trade-off for correctness and thread safety. For typical use cases (< 50 concurrent threads), the performance impact is negligible.

Note:

Thread Safety: The mutex ensures that Faker::Config.random is correctly set and restored for each call, preventing race conditions in multi-threaded environments. Each Engine instance has its own FakerAdapter with its own Random instance, ensuring deterministic output per Engine.

Adapter for Faker that uses per-instance Random

Wraps all Faker calls to use a specific Random instance instead of modifying global Faker::Config.random. This enables thread-safe concurrent generation with different seeds.

Examples:

Create adapter with RNG

rng = RNG.new(42)
faker = FakerAdapter.new(rng)
faker.name  # => "John Smith" (deterministic with seed 42)

Class Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(rng) ⇒ FakerAdapter

Create a new FakerAdapter

Parameters:

  • rng (RNG)

    the random number generator to use



69
70
71
72
# File 'lib/synthra/generator/faker_adapter.rb', line 69

def initialize(rng)
  @rng = rng
  @faker_random = Random.new(rng.seed)
end

Class Attribute Details

.mutexObject (readonly)

Returns the value of attribute mutex.



60
61
62
# File 'lib/synthra/generator/faker_adapter.rb', line 60

def mutex
  @mutex
end

Instance Method Details

#airlineString

Generate an airline name using Faker

Returns:

  • (String)

    generated airline name



282
283
284
# File 'lib/synthra/generator/faker_adapter.rb', line 282

def airline
  with_faker_random { Faker::Airline.name }
end

#blood_typeString

Generate a blood type using Faker

Returns:

  • (String)

    generated blood type



292
293
294
# File 'lib/synthra/generator/faker_adapter.rb', line 292

def blood_type
  with_faker_random { Faker::Blood.type }
end

#buzzwordString

Generate a buzzword using Faker

Returns:

  • (String)

    generated buzzword



352
353
354
# File 'lib/synthra/generator/faker_adapter.rb', line 352

def buzzword
  with_faker_random { Faker::Company.buzzword }
end

#catch_phraseString

Generate a catch phrase using Faker

Returns:

  • (String)

    generated catch phrase



362
363
364
# File 'lib/synthra/generator/faker_adapter.rb', line 362

def catch_phrase
  with_faker_random { Faker::Company.catch_phrase }
end

#characters(number:, locale: nil) ⇒ String

Generate text characters using Faker

Parameters:

  • number (Integer)

    number of characters to generate

  • locale (Symbol) (defaults to: nil)

    locale to use (e.g., :en, :ar, :es)

Returns:

  • (String)

    generated text



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/synthra/generator/faker_adapter.rb', line 142

def characters(number:, locale: nil)
  with_faker_random do
    if locale && Faker::Config.respond_to?(:locale=)
      original_locale = Faker::Config.locale
      begin
        Faker::Config.locale = locale
        Faker::Lorem.characters(number: number)
      rescue StandardError
        # :nocov:
        # If locale not supported, fallback to current locale
        Faker::Lorem.characters(number: number)
        # :nocov:
      ensure
        Faker::Config.locale = original_locale
      end
    else
      Faker::Lorem.characters(number: number)
    end
  end
end

#cityString

Generate a city using Faker

Returns:

  • (String)

    generated city



302
303
304
# File 'lib/synthra/generator/faker_adapter.rb', line 302

def city
  with_faker_random { Faker::Address.city }
end

#colorString

Generate a color using Faker

Returns:

  • (String)

    generated color



372
373
374
# File 'lib/synthra/generator/faker_adapter.rb', line 372

def color
  with_faker_random { Faker::Commerce.color }
end

#company_nameString

Generate a company name using Faker

Returns:

  • (String)

    generated company name



342
343
344
# File 'lib/synthra/generator/faker_adapter.rb', line 342

def company_name
  with_faker_random { Faker::Company.name }
end

#country_codeString

Generate a country code using Faker

Returns:

  • (String)

    generated country code



169
170
171
# File 'lib/synthra/generator/faker_adapter.rb', line 169

def country_code
  with_faker_random { Faker::Address.country_code }
end

#currency_codeString

Generate a currency code using Faker

Returns:

  • (String)

    generated currency code



179
180
181
# File 'lib/synthra/generator/faker_adapter.rb', line 179

def currency_code
  with_faker_random { Faker::Currency.code }
end

#date_backward(days:) ⇒ Date

Generate a date in the past using Faker

Parameters:

  • days (Integer)

    number of days in the past

Returns:

  • (Date)

    generated date



210
211
212
# File 'lib/synthra/generator/faker_adapter.rb', line 210

def date_backward(days:)
  with_faker_random { Faker::Date.backward(days: days) }
end

#date_forward(days:) ⇒ Date

Generate a date in the future using Faker

Parameters:

  • days (Integer)

    number of days in the future

Returns:

  • (Date)

    generated date



221
222
223
# File 'lib/synthra/generator/faker_adapter.rb', line 221

def date_forward(days:)
  with_faker_random { Faker::Date.forward(days: days) }
end

#emailString

Generate an email using Faker

Returns:

  • (String)

    generated email



90
91
92
# File 'lib/synthra/generator/faker_adapter.rb', line 90

def email
  with_faker_random { Faker::Internet.email }
end

#female_first_nameString

Generate a female first name using Faker

Returns:

  • (String)

    generated female first name



382
383
384
# File 'lib/synthra/generator/faker_adapter.rb', line 382

def female_first_name
  with_faker_random { Faker::Name.female_first_name }
end

#first_nameString

Generate a first name using Faker

Returns:

  • (String)

    generated first name



262
263
264
# File 'lib/synthra/generator/faker_adapter.rb', line 262

def first_name
  with_faker_random { Faker::Name.first_name }
end

#genderString

Generate a gender using Faker

Returns:

  • (String)

    generated gender



242
243
244
# File 'lib/synthra/generator/faker_adapter.rb', line 242

def gender
  with_faker_random { Faker::Gender.type }
end

#ip_v4_addressString

Generate an IPv4 address using Faker

Returns:

  • (String)

    generated IPv4 address



120
121
122
# File 'lib/synthra/generator/faker_adapter.rb', line 120

def ip_v4_address
  with_faker_random { Faker::Internet.ip_v4_address }
end

#ip_v6_addressString

Generate an IPv6 address using Faker

Returns:

  • (String)

    generated IPv6 address



130
131
132
# File 'lib/synthra/generator/faker_adapter.rb', line 130

def ip_v6_address
  with_faker_random { Faker::Internet.ip_v6_address }
end

#last_nameString

Generate a last name using Faker

Returns:

  • (String)

    generated last name



272
273
274
# File 'lib/synthra/generator/faker_adapter.rb', line 272

def last_name
  with_faker_random { Faker::Name.last_name }
end

#male_first_nameString

Generate a male first name using Faker

Returns:

  • (String)

    generated male first name



392
393
394
# File 'lib/synthra/generator/faker_adapter.rb', line 392

def male_first_name
  with_faker_random { Faker::Name.male_first_name }
end

#nameString

Generate a name using Faker

Returns:

  • (String)

    generated name



80
81
82
# File 'lib/synthra/generator/faker_adapter.rb', line 80

def name
  with_faker_random { Faker::Name.name }
end

#phone_numberString

Generate a phone number using Faker

Returns:

  • (String)

    generated phone number



100
101
102
# File 'lib/synthra/generator/faker_adapter.rb', line 100

def phone_number
  with_faker_random { Faker::PhoneNumber.phone_number }
end

#postcodeString

Generate a postcode using Faker

Returns:

  • (String)

    generated postcode



199
200
201
# File 'lib/synthra/generator/faker_adapter.rb', line 199

def postcode
  with_faker_random { Faker::Address.postcode }
end

#stateString

Generate a state using Faker

Returns:

  • (String)

    generated state



312
313
314
# File 'lib/synthra/generator/faker_adapter.rb', line 312

def state
  with_faker_random { Faker::Address.state }
end

#street_addressString

Generate a street address using Faker

Returns:

  • (String)

    generated street address



322
323
324
# File 'lib/synthra/generator/faker_adapter.rb', line 322

def street_address
  with_faker_random { Faker::Address.street_address }
end

#street_nameString

Generate a street name using Faker

Returns:

  • (String)

    generated street name



332
333
334
# File 'lib/synthra/generator/faker_adapter.rb', line 332

def street_name
  with_faker_random { Faker::Address.street_name }
end

#time_backward(days:) ⇒ Time

Generate a time in the past using Faker

Parameters:

  • days (Integer)

    number of days in the past

Returns:

  • (Time)

    generated time



232
233
234
# File 'lib/synthra/generator/faker_adapter.rb', line 232

def time_backward(days:)
  with_faker_random { Faker::Time.backward(days: days) }
end

#time_zoneString

Generate a timezone using Faker

Returns:

  • (String)

    generated timezone



252
253
254
# File 'lib/synthra/generator/faker_adapter.rb', line 252

def time_zone
  with_faker_random { Faker::Address.time_zone }
end

#urlString

Generate a URL using Faker

Returns:

  • (String)

    generated URL



110
111
112
# File 'lib/synthra/generator/faker_adapter.rb', line 110

def url
  with_faker_random { Faker::Internet.url }
end

#with_faker_random { ... } ⇒ Object (private)

Temporarily set Faker's random and execute block

This method synchronizes access to Faker::Config.random to ensure thread safety. It saves the current random, sets ours, executes the block, then restores the original.

Yields:

  • [] block to execute with our random

Returns:

  • (Object)

    result of block



409
410
411
412
413
414
415
416
417
418
419
420
421
# File 'lib/synthra/generator/faker_adapter.rb', line 409

def with_faker_random

  # Use class-level mutex to synchronize access to global Faker state
  self.class.mutex.synchronize do
    old_random = Faker::Config.random
    begin
      Faker::Config.random = @faker_random
      yield
    ensure
      Faker::Config.random = old_random
    end
  end
end

#zip_codeString

Generate a zip code using Faker

Returns:

  • (String)

    generated zip code



189
190
191
# File 'lib/synthra/generator/faker_adapter.rb', line 189

def zip_code
  with_faker_random { Faker::Address.zip_code }
end