#StackBounty: #android #design-patterns #android-contentprovider #android-contentresolver #android-mvp Is Content Observer an implement…

Bounty: 50

Observer Pattern is defined by the ‘Gang of Four’ Design Patterns book as a “one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically“.
enter image description here

They also say that the Observer pattern should be used in any of the following situations:

  • When an abstraction has two aspects, one dependent on the
    other. Encapsulating these aspects in separate objects lets you vary and reuse them independently.

  • When a change to one object requires changing others, and you don’t know how many objects need to be changed.

  • When an object should be able to notify other objects without making
    assumptions about who these objects are. In other words, you don’t
    want these objects tightly coupled.

On Adam Stroud Android Database Best Practices book it states that “the Cursor class provides the methods that expose the Observer pattern to a source of data. And, by using these methods, it is possible to respond to data changes using the Observer Pattern rather than polling the database for changes, which can be inefficient”:

  • Cursor.registerContentObserver()

  • Cursor.unregisterContentObserver()

  • Cursor.setNotificationUri()

Similarly, by using a ContentProvider, we can use a ContentResolver client object to access the data from the Content Provider and then register a ContentObserver to listen to the change of data behind the URI the observer was registered for.

So, as the Subject object in the Observer pattern, ContentResolver has the methods that, by my thinking, are almost the same:

enter image description here

  • registerContentObserver() of ContentResolver is Attach() from Subject

  • unregisterContentObserver() of ContentResolver is Dettach() from Subject

  • notifyChange() of ContentResolver is Notify() from Subject

So, my question is, if the three components of a ContentProvider (ContentProvider, ContentResolver, and ContentObserver) are by themselves an implementation of the Observer pattern?


Get this bounty!!!

#StackBounty: #object-oriented #design-patterns #swift #ios Swift/iOS component for label with clickable text buttons

Bounty: 100

So I’m creating a component based on UILabel, which I’m calling RichLabel. The main goal is to add support for clickable links (multiple). It should also be possible to to differentiate between types of links, so I can handle them differently. For instance one link should open ModalWindowA and another ModalWindowB.

I have something that works, but it’s not a very solid solution, and would love some input on the design.

RichButton

RichButton is the different types of button/links I currently support in the RichText.

protocol RichButton {
  var id: String { get }
  var buttonTitle: String { get }
}

struct ProfileRichButton: RichButton {

  let id: String
  let buttonTitle: String

  init(id: String = UUID().uuidString, buttonTitle: String) {
    self.id = id
    self.buttonTitle = buttonTitle
  }

}

struct AttendeesRichButton: RichButton {

  let id: String
  let buttonTitle: String

  init(id: String = UUID().uuidString, buttonTitle: String) {
    self.id = id
    self.buttonTitle = buttonTitle
  }

}

struct MeetingRichButton: RichButton {

  let id: String
  let buttonTitle: String

  init(id: String = UUID().uuidString, buttonTitle: String) {
    self.id = id
    self.buttonTitle = buttonTitle
  }

}

RichLabelComponent

RichLabelComponent is holding the data for the RichLabelComponentView and formats the text and highlights the clickable text.

protocol Component {
  var id: String { get }
}

struct RichLabelComponent: Component {

  let id: String
  let text: String
  let buttons: [RichButton]

  var formattedText: String {
    let buttonTitles = buttons.map { $0.buttonTitle }
    let formattedString = String(format: text, arguments: buttonTitles)
    return formattedString
  }

  var attributedText: NSAttributedString? {
    let attributedText = NSMutableAttributedString(string: formattedText)
    let nsFormattedText = NSString(string: formattedText)
    attributedText.setAttributes([.font: Theme.regular(size: .large)], range: formattedText.whole)
    for button in buttons {
      let range = nsFormattedText.range(of: button.buttonTitle)
      let attributedButtonTitle = NSAttributedString(string: button.buttonTitle, attributes: [.foregroundColor: Theme.secondaryOrangeColor, .font: Theme.regular(size: .large)])
      attributedText.replaceCharacters(in: range, with: attributedButtonTitle)
    }
    return attributedText
  }

  init(id: String = UUID().uuidString, text: String) {
    self.id = id
    self.text = text
    self.buttons = []
  }

  init(id: String = UUID().uuidString, text: String, buttons: RichButton...) {
    self.id = id
    self.text = text
    self.buttons = buttons
  }
}

RichLabelComponentView

This is the view responsible for displaying the formatted label, and handles the tapGesture.

protocol RichLabelComponentViewDelegate: class {
  func richLabelComponentView(_ richLabelComponentView:   RichLabelComponentView, didTapButton button: RichButton, forComponent  component: RichLabelComponent)
}

class RichLabelComponentView: UIView {

  // MARK: - Internal properties

  private lazy var label: UILabel = {
    let label = UILabel()
    label.numberOfLines = 0
    label.lineBreakMode = .byWordWrapping
    label.textAlignment = .left
    label.isUserInteractionEnabled = true
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
  }()

  private lazy var tapGestureRecognizer: UITapGestureRecognizer = {
    let tapGestureRecognizer = UITapGestureRecognizer()
    tapGestureRecognizer.addTarget(self, action: #selector(tapHandler(gesture:)))
    return tapGestureRecognizer
  }()

  // MARK: - External properties

  weak var delegate: RichLabelComponentViewDelegate?

  var component: RichLabelComponent? {
    didSet {
      label.attributedText = component?.attributedText
    }
  }

  // MARK: - Setup

  override init(frame: CGRect) {
    super.init(frame: frame)
    self.addGestureRecognizer(tapGestureRecognizer)
    self.addSubviewsAndConstraints()
  }

  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }

  private func addSubviewsAndConstraints() {
    addSubview(label)

    label.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
    label.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
    label.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
    label.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
  }

  // MARK: - Actions

  @objc func tapHandler(gesture: UITapGestureRecognizer) {
    guard let component = component, let delegate = delegate else {
      return
    }

    for button in component.buttons {
      let nsString = component.formattedText as NSString
      let range = nsString.range(of: button.buttonTitle)
      if tapGestureRecognizer.didTapAttributedText(label: label, inRange: range) {
        delegate.richLabelComponentView(self, didTapButton: button, forComponent: component)
      }
    }
  }
}

This is the implementation which recognises if one of the text links/buttons where tapped:

extension UIGestureRecognizer {

  /**
   Returns `true` if the tap gesture was within the specified range of the attributed text of the label.

   - Parameter label:   The label to match tap gestures in.
   - Parameter targetRange: The range for the substring we want to match tap against.

   - Returns: A boolean value indication wether substring where tapped or not.
   */
  func didTapAttributedText(label: UILabel, inRange targetRange: NSRange) -> Bool {
    guard let attributedString = label.attributedText else { fatalError("Not able to fetch attributed string.") }

    var offsetXDivisor: CGFloat
    switch label.textAlignment {
    case .center: offsetXDivisor = 0.5
    case .right: offsetXDivisor = 1.0
    default: offsetXDivisor = 0.0
    }

    let layoutManager = NSLayoutManager()
    let textContainer = NSTextContainer(size: .zero)
    let textStorage = NSTextStorage(attributedString: attributedString)
    let labelSize = label.bounds.size

    layoutManager.addTextContainer(textContainer)
    textStorage.addLayoutManager(layoutManager)

    textContainer.lineFragmentPadding = 0.0
    textContainer.lineBreakMode = label.lineBreakMode
    textContainer.maximumNumberOfLines = label.numberOfLines
    textContainer.size = labelSize

    let locationOfTouchInLabel = self.location(in: label)
    let textBoundingBox = layoutManager.usedRect(for: textContainer)

    let offsetX = (labelSize.width - textBoundingBox.size.width) * offsetXDivisor - textBoundingBox.origin.x
    let offsetY = (labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y
    let textContainerOffset = CGPoint(x: offsetX, y: offsetY)

    let locationTouchX = locationOfTouchInLabel.x - textContainerOffset.x
    let locationTouchY = locationOfTouchInLabel.y - textContainerOffset.y
    let locationOfTouch = CGPoint(x: locationTouchX, y: locationTouchY)

    let indexOfCharacter = layoutManager.characterIndex(for: locationOfTouch, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)

    return NSLocationInRange(indexOfCharacter, targetRange)
  }
}

How to use the component

let component = RichLabelComponent(text: "Hello %@. You are meeting with %@.", buttons: ProfileRichButton(buttonTitle: "Your Name"), AttendeesRichButton(buttonTitle: "Eve and Bob"))
let view = RichLabelComponentView()
view.component = component
view.delegate = self

I can then send button, and on the delegate method I can then switch on button.self and check for case is ProfileRichButton for instance, so I can know which type of link was clicked.

The problems

What I don’t like about this solution is for instance the need to use NSString.range(of: "") to set properties. If suddenly there are two links with same name, this won’t work.

Any ideas how to improve this or restructure it in a more flexible and solid way?


Get this bounty!!!

#StackBounty: #java #object-oriented #multithreading #design-patterns #thread-safety Send records to messaging queue using either of on…

Bounty: 50

I have bunch of keys (clientKey) and values (processBytes) that I want to send to our messaging queue by packing them in one byte array. I will make one byte array of all the keys and values which should always be less than 50K and then send to our messaging queue.

For each partition, I have bunch of dataHolders so I am iterating those and then sending it to my messaging queue:

private void validateAndSend(final DataPartition partition) {
  final ConcurrentLinkedQueue<DataHolder> dataHolders = dataHoldersByPartition.get(partition);

  // sending data via async policy
  final Packet packet = new Packet(partition, new QPolicyAsync());

  DataHolder dataHolder;
  while ((dataHolder = dataHolders.poll()) != null) {
    packet.addAndSendJunked(dataHolder.getClientKey().getBytes(StandardCharsets.UTF_8),
        dataHolder.getProcessBytes());
  }
  packet.close();
}

Packet class: This class packs all the keys and values into one byte array and call corresponding implementation passed in the constructor to send data to queue.

public final class Packet implements Closeable {
  private static final int MAX_SIZE = 50000;
  private static final int HEADER_SIZE = 36;

  private final byte dataCenter;
  private final byte recordVersion;
  private final long address;
  private final long addressFrom;
  private final long addressOrigin;
  private final byte partition;
  private final byte replicated;
  private final ByteBuffer itemBuffer = ByteBuffer.allocate(MAX_SIZE);
  private final QueuePolicy policy;
  private int pendingItems = 0;

  public Packet(final DataPartition partition, final QueuePolicy policy) {
    this.partition = (byte) partition.getPartition();
    this.policy = policy;
    this.dataCenter = Utils.LOCATION.get().datacenter();
    this.recordVersion = 1;
    this.replicated = 0;
    final long packedAddress = new Data().packAddress();
    this.address = packedAddress;
    this.addressFrom = 0L;
    this.addressOrigin = packedAddress;
  }

  private void addHeader(final ByteBuffer buffer, final int items) {
    buffer.put(dataCenter).put(recordVersion).putInt(items).putInt(buffer.capacity())
        .putLong(address).putLong(addressFrom).putLong(addressOrigin).put(partition)
        .put(replicated);
  }

  private void sendData() {
    if (itemBuffer.position() == 0) {
      // no data to be sent
      return;
    }
    final ByteBuffer buffer = ByteBuffer.allocate(MAX_SIZE);
    addHeader(buffer, pendingItems);
    buffer.put(itemBuffer);
    // sending data via particular policy
    policy.sendToQueue(address, buffer.array());
    itemBuffer.clear();
    pendingItems = 0;
  }

  public void addAndSendJunked(final byte[] key, final byte[] data) {
    if (key.length > 255) {
      return;
    }
    final byte keyLength = (byte) key.length;
    final byte dataLength = (byte) data.length;

    final int additionalSize = dataLength + keyLength + 1 + 1 + 8 + 2;
    final int newSize = itemBuffer.position() + additionalSize;
    if (newSize >= (MAX_SIZE - HEADER_SIZE)) {
      sendData();
    }
    if (additionalSize > (MAX_SIZE - HEADER_SIZE)) {
      throw new AppConfigurationException("Size of single item exceeds maximum size");
    }

    final ByteBuffer dataBuffer = ByteBuffer.wrap(data);
    final long timestamp = dataLength > 10 ? dataBuffer.getLong(2) : System.currentTimeMillis();
    // data layout
    itemBuffer.put((byte) 0).put(keyLength).put(key).putLong(timestamp).putShort(dataLength)
        .put(data);
    pendingItems++;
  }

  @Override
  public void close() {
    if (pendingItems > 0) {
      sendData();
    }
  }
}

Now I can send data to my messaging queue in three different ways so for that I created an interface and then having three different implementations:

QueuePolicy interface:

public interface QueuePolicy {
    public boolean sendToQueue(final long address, final byte[] encodedRecords);
}

QPolicyAsync class:

public class QPolicyAsync implements QueuePolicy {

  @Override
  public boolean sendToQueue(long address, byte[] encodedRecords) {
    return SendRecord.getInstance().sendToQueueAsync(address, encodedRecords);
  }
}

QPolicySync class:

public class QPolicySync implements QueuePolicy {

  @Override
  public boolean sendToQueue(long address, byte[] encodedRecords) {
    return SendRecord.getInstance().sendToQueueSync(address, encodedRecords);
  }
}

QPolicySyncWithSocket class:

public class QPolicySyncWithSocket implements QueuePolicy {
  private final Socket socket;

  public QPolicySyncWithSocket(Socket socket) {
    this.socket = socket;
  }

  @Override
  public boolean sendToQueue(long address, byte[] encodedRecords) {
    return SendRecord.getInstance().sendToQueueSync(address, encodedRecords, Optional.of(socket));
  }
}

SendRecord class: This is the actual class which sends data to my messaging queue. It has three different implementations (numbered with 1, 2, 3 as comments) in it and each of those implementations is being called from above QueuePolicy implementations:

public class SendRecord {
  private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);
  private final Cache<Long, PendingMessage> cache = CacheBuilder.newBuilder().maximumSize(1000000)
      .concurrencyLevel(100).build();

  private static class Holder {
    private static final SendRecord INSTANCE = new SendRecord();
  }

  public static SendRecord getInstance() {
    return Holder.INSTANCE;
  }

  private SendRecord() {
    executorService.scheduleAtFixedRate(new Runnable() {
      @Override
      public void run() {
        handleRetry();
      }
    }, 0, 1, TimeUnit.SECONDS);
  }

  // this will retry to send data again if acknowledgment is not received
  // but only for async cases. For sync we don't retry at all
  private void handleRetry() {
    List<PendingMessage> messages = new ArrayList<>(cache.asMap().values());
    for (PendingMessage message : messages) {
      if (message.hasExpired()) {
        if (message.shouldRetry()) {
          message.markResent();
          doSendAsync(message, Optional.<Socket>absent());
        } else {
          cache.invalidate(message.getAddress());
        }
      }
    }
  }

  // #1 sends data asynchronously
  public boolean sendToQueueAsync(final long address, final byte[] encodedRecords) {
    PendingMessage m = new PendingMessage(address, encodedRecords, true);
    cache.put(address, m);
    return doSendAsync(m, Optional.<Socket>absent());
  }

  // place where we send data on a socket
  private boolean doSendAsync(final PendingMessage message, final Optional<Socket> socket) {
    Optional<Socket> actualSocket = socket;
    if (!actualSocket.isPresent()) {
      SocketState liveSocket = SocketPoolManager.getInstance().getSocket();
      actualSocket = Optional.of(liveSocket.getSocket());
    }

    ZMsg msg = new ZMsg();
    msg.add(message.getEncodedRecords());
    try {
      return msg.send(actualSocket.get());
    } finally {
      msg.destroy();
    }
  }

  // #2 sends data synchronously without taking socket as a parameter
  public boolean sendToQueueSync(final long address, final byte[] encodedRecords) {
    return sendToQueueSync(address, encodedRecords, Optional.<Socket>absent());
  }

  // #3 sends data synchronously but by taking socket as a parameter
  public boolean sendToQueueSync(final long address, final byte[] encodedRecords,
      final Optional<Socket> socket) {
    PendingMessage m = new PendingMessage(address, encodedRecords, false);
    cache.put(address, m);
    try {
      if (doSendAsync(m, socket)) {
        return m.waitForAck();
      }
    } finally {
      cache.invalidate(address);
    }
    return false;
  }

  // called by ResponsePoller thread to tell us that messaging queue
  // has received data
  public void handleAckReceived(final long address) {
    PendingMessage message = cache.getIfPresent(address);
    if (message != null) {
      message.ackReceived();
      cache.invalidate(address);
    }
  }
}

I have my code working fine. The idea is very simple: I am sending data to my messaging queue via either of those three QueuePolicy implementations. It depends on how clients want to send data. As of now I am passing implementation of QueuePolicy in the Packet constructor and then sends data via that policy. Each QueuePolicy implementation calls corresponding method in SendRecord class.

  • Does my Packet class needs to know on how data is being sent? I think Packet class is just a container, and that’s all it is. I think we shouldn’t expect it to know how to transmit itself. A transmitter does that.
  • Also, each QueuePolicy implementation calls corresponding method of SendRecord class. Is this really needed or there is any better way? Can we not get rid of SendRecord class and have them implemented in each of these three QueuePolicy implementations?

I believe with my design, I might be breaking Single Responsibility Principle or not following oops standard properly so wanted to see if we can design this efficiently and if there is any better way? What is the best way by which we can send key(s) and value(s) by packing them in one byte array (following that 50K limit) either through sync or async mode?


Get this bounty!!!

#StackBounty: #c# #design-patterns #asp.net-mvc CQS implementation with decorators

Bounty: 50

I’ve created a “framework” or more of a library for a CQS implementation with a few decorators. Using ASP.NET Core for the front end, I wanted an opinion about how this looks/feels. I changed the default mvc approach and created a Features folder that stores both the Views and Controllers in the same folder. Then each command/query ends up being in its own folder in the implementation. I have the following decorators: Exception/Logging, Retry, Cache, Cache Invalidation, Validation, and Permission. Any input at all is welcomed!

This will be along post, but it’ll be an interesting read, in my opinion. 🙂

First, CQS = Command Query Separation. Essentially, queries return data and do not modify state and commands modify state but return no data. There is a gray area here where you need to run a command but then return the data (i.e. Queues, Stacks). Thus, i Created a “CommandQuery” for those scenarios where just a command won’t be good enough. CQS normally has ICommandHandler<> and IQueryHandler<> interfaces to support decorators. Decorators are classes that can add functionality to these classes without changing them. i.e. The calls are chained. They implement the same interface, but I use SimpleInjector to make those classes run before/after the actual implementation. All code becomes narrow and easy to maintain. Also, you can add more decorators to all commands/queries with one line of code.

I tried to follow SOLID through all the layers here with the intention that every piece of code will be unit testable at a high level. The problems being solved inside may end up more difficult than that, but I digress. 🙂

(My mock implementation deals with Digimon World 2… Don’t ask) 🙂

Controller

[Route(ApiConstants.RootApiUrlVersion1 + "DigimonWorld2Admin/Digimon/Create")]
public class CreateCommandQueryController : MetalKidApiControllerBase
{
    private readonly IResponseMediator _responseMediator;

    public CreateCommandQueryController(IResponseMediator responseMediator) =>
        _responseMediator = responseMediator;

    [HttpPost]
    public async Task<IActionResult> Post([FromBody] CreateCommandQuery commandQuery) =>
        await _responseMediator.ExecuteAsync(commandQuery).ConfigureAwait(false);
}

Since we can route the different verbs to different classes, we can focus on only 1 method at a time per class. I’m using Mediators everywhere so the code looks the same across all classes. I thought this was really the Service Locator anti-pattern, but it isn’t because you still know the mediator dependency. I also use async through the entire call stack because Task.CompletedTask, if needed, has very little overhead and not blocking threads is the way to go.

ResponseMediator

public class ResponseMediator : IResponseMediator
{
    private readonly ICqsMediator _mediator;
    private readonly ICommonResource _resource;

    public ResponseMediator(ICqsMediator mediator, ICommonResource resource)
    {
        Guard.IsNotNull(mediator, nameof(mediator));

        _mediator = mediator;
        _resource = resource;
    }

    public async Task<IActionResult> ExecuteAsync(
        ICommand command, CancellationToken token = default(CancellationToken)) =>
        HandleResult(await _mediator.ExecuteAsync(command, token).ConfigureAwait(false));

    public async Task<IActionResult> ExecuteAsync<TResponse>(
        ICommandQuery<TResponse> query, CancellationToken token = default(CancellationToken)) =>
        HandleResult(await _mediator.ExecuteAsync(query, token).ConfigureAwait(false));

    public async Task<IActionResult> ExecuteAsync<TResponse>(
        IQuery<TResponse> query, CancellationToken token = default(CancellationToken)) =>
        HandleResult(await _mediator.ExecuteAsync(query, token).ConfigureAwait(false));

    private IActionResult HandleResult<T>(IResult<T> result)
    {
        if (result.IsSuccessful)
        {
            return new OkObjectResult(result.Data);
        }
        return HandleResult((IResult)result);
    }

    private IActionResult HandleResult(IResult result)
    {
        if (result.IsSuccessful)
        {
            return new OkResult();
        }
        if (result.BrokenRules?.Any() == true)
        {
            return new BadRequestObjectResult(new {result.BrokenRules});
        }
        if (result.HasConcurrencyError)
        {
            return new BadRequestObjectResult(new {Message = _resource.ErrorConcurrency});
        }
        if (result.HasNoPermissionError)
        {
            return new UnauthorizedResult();
        }
        if (result.HasNoDataFoundError)
        {
            return new NotFoundResult();
        }
        if (!string.IsNullOrEmpty(result.ErrorMessage))
        {
            return new BadRequestObjectResult(new {Message = result.ErrorMessage});
        }
        return new BadRequestObjectResult(new {Message = _resource.ErrorGeneric});
    }
}

All my queries/commands/command queries end up returning IResult because I found throwing exceptions is really expensive. Thus, this lets me deal with any issues. IResult is returned by Command and doesn’t return any info about the actual call, so it doesn’t violate CQS. Query returns IResult< T > that stores the data.

I’ll show an example here of the Create Command through the layers.

CommandQuery

public class CreateCommandQuery : ICommandQuery<int>, ICommandQueryRetry
{
    public string Name { get; set; }
    public int DigimonTypeId { get; set; }
    public int RankId { get; set; }
    public int? LearnedSkillId { get; set; }
    public int? SpecialtyId { get; set; }
    public string Found { get; set; }
    public bool? HasImage { get; set; }
    public int? HP { get; set; }
    public int? MP { get; set; }
    public int? Att { get; set; }
    public int? Def { get; set; }
    public int? Speed { get; set; }

    int ICommandQueryRetry.MaxRetries => 3;
}

ICommandQueryRetry will cause this to retry general exceptions up to 3 times before failing.

For caching, you just add a different interfaces (a few different ones for different timeframes) and it takes care of it for you.

public class ListQuery : IQuery<ICollection<ListDto>>, IQueryCacheableAbsoluteTimespan
{
    public string Name { get; set; }

    TimeSpan IQueryCacheableAbsoluteTimespan.ExpireTimeout => TimeSpan.FromDays(1);
}

CommandQueryHandler

public class CreateCommandQueryHandler : ICommandQueryHandler<CreateCommandQuery, int>
{
    private readonly IRepositoryMediator _repositoryMediator;

    public CreateCommandQueryHandler(IRepositoryMediator repositoryMediator) =>
        _repositoryMediator = repositoryMediator;

    public async Task<IResult<int>> ExecuteAsync(
        CreateCommandQuery commandQuery, CancellationToken token = default(CancellationToken))
    {
        var digimonId = await _repositoryMediator.ExecuteAsync<int>(commandQuery, token).ConfigureAwait(false);
        return ResultHelper.Successful(digimonId);
    }
}

Validation

The validation decorator will run validation on multiple threads (if you want) and async will not block. I didn’t use expressions since a lot of times validation involves multiple properties and has a lot of overhead. The BrokenRule() parameter is the “Relation” and it can be used to tie the rule somewhere on the UI.

public class CreateCommandQueryValidator : CommandQueryValidatorBase<CreateCommandQuery, int>
{
    private readonly IValidationRepositoryMediator _validationRepositoryMediator;
    private readonly IDigimonWorld2AdminResources _resources;

    public CreateCommandQueryValidator(IValidationRepositoryMediator validationRepositoryMediator,
        IDigimonWorld2AdminResources resources)
    {
        _validationRepositoryMediator = validationRepositoryMediator;
        _resources = resources;
    }

    protected override void CreateRules(CancellationToken token = default(CancellationToken))
    {
        AddRules(
            () => Validate.If(string.IsNullOrEmpty(CommandQuery.Name))?.BrokenRule(nameof(CommandQuery.Name))
                .Required(_resources.DigimonCreateCommandName),
            () => Validate.If(CommandQuery.DigimonTypeId == 0)?.BrokenRule(nameof(CommandQuery.DigimonTypeId))
                .Required(_resources.DigimonCreateCommandDigimonTypeId),
            () => Validate.If(CommandQuery.RankId == 0)?.BrokenRule(nameof(CommandQuery.RankId))
                .Required(_resources.DigimonCreateCommandRankId)
        );

        AddRules(_validationRepositoryMediator.GetValidationRules(CommandQuery, token));
    }
}

public class CreateCommandQueryValidationRepository : IValidationRepository<CreateCommandQuery>
{
    private readonly IValidator _validate;
    private readonly IDigimonWorld2ContextFactory _contextFactory;
    private readonly IDigimonWorld2AdminResources _resources;

    public CreateCommandQueryValidationRepository(IValidator validate, IDigimonWorld2ContextFactory contextFactory,
        IDigimonWorld2AdminResources resources)
    {
        _validate = validate;
        _contextFactory = contextFactory;
        _resources = resources;
    }

    public ICollection<Func<Task<BrokenRule>>> GetValidationRules(
        CreateCommandQuery request, CancellationToken token = default(CancellationToken)) =>
        new List<Func<Task<BrokenRule>>>(1)
        {
            async () =>
            {
                using (var context = _contextFactory.Create(false))
                {
                    return _validate.If(
                            !string.IsNullOrEmpty(request.Name) &&
                            await context.Digimons
                                .AnyAsync(a => a.Name.Equals(request.Name, StringComparison.OrdinalIgnoreCase),
                                    token)
                                .ConfigureAwait(false))?.BrokenRule(nameof(request.Name))
                        .AlreadyInUse(_resources.DigimonCreateCommandName, request.Name);
                }
            }
        };
}

Validation uses ?. here so that the second part isn’t run if there is no rule. .NET Core changed the way translations work, so I had to IoC inject a reference to them now, which is why you see that.

CreateCommandRepository

public class CreateCommandQueryRepository : IRepository<CreateCommandQuery, int>
{
    private const int ExpectedRowsAffected = 1;

    private readonly IDigimonWorld2ContextFactory _contextFactory;
    private readonly IMapperMediator _mapperMediator;

    public CreateCommandQueryRepository(
        IDigimonWorld2ContextFactory contextFactory,
        IMapperMediator mapperMediator)
    {
        _contextFactory = contextFactory;
        _mapperMediator = mapperMediator;
    }

    public async Task<int> ExecuteAsync(CreateCommandQuery request, CancellationToken token = default(CancellationToken))
    {
        using (var context = _contextFactory.Create())
        {
            var entity = _mapperMediator.Map<DigimonEntity>(request);
            context.Digimons.Add(entity);

            await context.SaveChangesAsync(ExpectedRowsAffected, token).ConfigureAwait(false);

            return entity.DigimonId;
        }
    }
}

My “repository” is a little different. The repository here is above the database technology being used. That way, if you want to change from EF to a webservice or something, you can change that implementation easily without affecting the handler above.

Mapper

public class CreateCommandQueryMapper : IMapper<CreateCommandQuery, DigimonEntity>
{
    public DigimonEntity Map(CreateCommandQuery command, DigimonEntity to = default(DigimonEntity))
    {
        to = to ?? new DigimonEntity();

        to.Name = command.Name;
        to.DigimonTypeId = command.DigimonTypeId;
        to.RankId = command.RankId;
        to.LearnedSkillId = command.LearnedSkillId;
        to.Att = command.Att;
        to.Def = command.Def;
        to.Found = command.Found;
        to.HasImage = command.HasImage;
        to.HP = command.HP;
        to.MP = command.MP;
        to.SpecialtyId = command.SpecialtyId;
        to.Speed = command.Speed;

        return to;
    }
}

I find if you do this in chunks together (all these classes, minus the controller) are all in the same folder as they are all related, that coding the mapping by hand isn’t that big of a deal. Though, I made this generic so you could setup your own that just used AutoMapper or whatever instead.

Invalidate Cache

public class CreateCommandQueryInvalidateCache : CacheManagerCommandQueryInvalidateCache<CreateCommandQuery, int>
{
    public CreateCommandQueryInvalidateCache(
        IQueryCacheRegion queryCacheRegion, 
        ICacheManager<object> cache) : base(queryCacheRegion, cache) { }

    protected override Task<ICollection<Type>> GetTypeOfQueriesToInvalidateAsync(
        CancellationToken token = default(CancellationToken)) =>
        Task.FromResult<ICollection<Type>>(new[] {typeof(ListQuery)});
}

If you know the queries you affect, you just have to give it the query type and it’ll take care of the rest. I made it async in case it took some IO to figure out all the types.

Decorators

The most important decorator I wanted to show was the exception handling one that is at the top of the chain:

public class CommandQueryHandlerExceptionDecorator<TCommandQuery, TResult> : ICommandQueryHandler<TCommandQuery, TResult>
    where TCommandQuery : ICommandQuery<TResult>
{
    private readonly ICommandQueryHandler<TCommandQuery, TResult> _commandQueryHandler;
    private readonly ILogger _logger;
    private readonly IUserContext _userContext;
    private readonly ICommonResource _resource;

    public CommandQueryHandlerExceptionDecorator(
        ICommandQueryHandler<TCommandQuery, TResult> commandQueryHandler, ILogger logger, IUserContext userContext,
        ICommonResource resource)
    {
        Guard.IsNotNull(commandQueryHandler, nameof(commandQueryHandler));
        Guard.IsNotNull(logger, nameof(logger));

        _commandQueryHandler = commandQueryHandler;
        _logger = logger;
        _userContext = userContext;
        _resource = resource;
    }

    public async Task<IResult<TResult>> ExecuteAsync(TCommandQuery commandQuery,
        CancellationToken token = default(CancellationToken))
    {
        try
        {
            return await _commandQueryHandler.ExecuteAsync(commandQuery, token).ConfigureAwait(false);
        }
        catch (UserFriendlyException ex)
        {
            await _logger.LogAsync(new LogEntry(LogTypeEnum.Error, _userContext,
                        "Friendly exception with command query: " + typeof(TCommandQuery).FullName, ex,
                        commandQuery),
                    token)
                .ConfigureAwait(false);
            return ResultHelper.Error<TResult>(ex.Message);
        }
        catch (DataNotFoundException ex)
        {
            await _logger.LogAsync(new LogEntry(LogTypeEnum.Error, _userContext,
                    "Data Not Found exception with command query: " + typeof(TCommandQuery).FullName, ex,
                    commandQuery), token)
                .ConfigureAwait(false);
            return ResultHelper.NoDataFoundError<TResult>();
        }
        catch (ConcurrencyException ex)
        {
            await _logger.LogAsync(new LogEntry(LogTypeEnum.Error, _userContext,
                        "Concurrency error with command query: " + typeof(TCommandQuery).FullName, ex,
                        commandQuery),
                    token)
                .ConfigureAwait(false);
            return ResultHelper.ConcurrencyError<TResult>();
        }
        catch (Exception ex)
        {
            await _logger.LogAsync(new LogEntry(LogTypeEnum.Error, _userContext,
                    "Error with command query: " + typeof(TCommandQuery).FullName, ex, commandQuery), token)
                .ConfigureAwait(false);
            return ResultHelper.Error<TResult>(_resource.ErrorGeneric);
        }
    }
}

If you are still reading and your eyes haven’t glazed over yet, what are your thoughts? Is this too much? Thanks!


Get this bounty!!!

#StackBounty: #c# #design-patterns CQS implementation with decorators

Bounty: 50

I’ve created a “framework” or more of a library for a CQS implementation with a few decorators. Using ASP.NET Core for the front end, I wanted an opinion about how this looks/feels. I changed the default mvc approach and created a Features folder that stores both the Views and Controllers in the same folder. Then each command/query ends up being in its own folder in the implementation. I have the following decorators: Exception/Logging, Retry, Cache, Cache Invalidation, Validation, and Permission. Any input at all is welcomed!

This will be along post, but it’ll be an interesting read, in my opinion. 🙂

First, CQS = Command Query Separation. Essentially, queries return data and do not modify state and commands modify state but return no data. There is a gray area here where you need to run a command but then return the data (i.e. Queues, Stacks). Thus, i Created a “CommandQuery” for those scenarios where just a command won’t be good enough. CQS normally has ICommandHandler<> and IQueryHandler<> interfaces to support decorators. Decorators are classes that can add functionality to these classes without changing them. i.e. The calls are chained. They implement the same interface, but I use SimpleInjector to make those classes run before/after the actual implementation. All code becomes narrow and easy to maintain. Also, you can add more decorators to all commands/queries with one line of code.

I tried to follow SOLID through all the layers here with the intention that every piece of code will be unit testable at a high level. The problems being solved inside may end up more difficult than that, but I digress. 🙂

(My mock implementation deals with Digimon World 2… Don’t ask) 🙂

Controller

[Route(ApiConstants.RootApiUrlVersion1 + "DigimonWorld2Admin/Digimon/Create")]
public class CreateCommandQueryController : MetalKidApiControllerBase
{
    private readonly IResponseMediator _responseMediator;

    public CreateCommandQueryController(IResponseMediator responseMediator) =>
        _responseMediator = responseMediator;

    [HttpPost]
    public async Task<IActionResult> Post([FromBody] CreateCommandQuery commandQuery) =>
        await _responseMediator.ExecuteAsync(commandQuery).ConfigureAwait(false);
}

Since we can route the different verbs to different classes, we can focus on only 1 method at a time per class. I’m using Mediators everywhere so the code looks the same across all classes. I thought this was really the Service Locator anti-pattern, but it isn’t because you still know the mediator dependency. I also use async through the entire call stack because Task.CompletedTask, if needed, has very little overhead and not blocking threads is the way to go.

ResponseMediator

public class ResponseMediator : IResponseMediator
{
    private readonly ICqsMediator _mediator;
    private readonly ICommonResource _resource;

    public ResponseMediator(ICqsMediator mediator, ICommonResource resource)
    {
        Guard.IsNotNull(mediator, nameof(mediator));

        _mediator = mediator;
        _resource = resource;
    }

    public async Task<IActionResult> ExecuteAsync(
        ICommand command, CancellationToken token = default(CancellationToken)) =>
        HandleResult(await _mediator.ExecuteAsync(command, token).ConfigureAwait(false));

    public async Task<IActionResult> ExecuteAsync<TResponse>(
        ICommandQuery<TResponse> query, CancellationToken token = default(CancellationToken)) =>
        HandleResult(await _mediator.ExecuteAsync(query, token).ConfigureAwait(false));

    public async Task<IActionResult> ExecuteAsync<TResponse>(
        IQuery<TResponse> query, CancellationToken token = default(CancellationToken)) =>
        HandleResult(await _mediator.ExecuteAsync(query, token).ConfigureAwait(false));

    private IActionResult HandleResult<T>(IResult<T> result)
    {
        if (result.IsSuccessful)
        {
            return new OkObjectResult(result.Data);
        }
        return HandleResult((IResult)result);
    }

    private IActionResult HandleResult(IResult result)
    {
        if (result.IsSuccessful)
        {
            return new OkResult();
        }
        if (result.BrokenRules?.Any() == true)
        {
            return new BadRequestObjectResult(new {result.BrokenRules});
        }
        if (result.HasConcurrencyError)
        {
            return new BadRequestObjectResult(new {Message = _resource.ErrorConcurrency});
        }
        if (result.HasNoPermissionError)
        {
            return new UnauthorizedResult();
        }
        if (result.HasNoDataFoundError)
        {
            return new NotFoundResult();
        }
        if (!string.IsNullOrEmpty(result.ErrorMessage))
        {
            return new BadRequestObjectResult(new {Message = result.ErrorMessage});
        }
        return new BadRequestObjectResult(new {Message = _resource.ErrorGeneric});
    }
}

All my queries/commands/command queries end up returning IResult because I found throwing exceptions is really expensive. Thus, this lets me deal with any issues. IResult is returned by Command and doesn’t return any info about the actual call, so it doesn’t violate CQS. Query returns IResult< T > that stores the data.

I’ll show an example here of the Create Command through the layers.

CommandQuery

public class CreateCommandQuery : ICommandQuery<int>, ICommandQueryRetry
{
    public string Name { get; set; }
    public int DigimonTypeId { get; set; }
    public int RankId { get; set; }
    public int? LearnedSkillId { get; set; }
    public int? SpecialtyId { get; set; }
    public string Found { get; set; }
    public bool? HasImage { get; set; }
    public int? HP { get; set; }
    public int? MP { get; set; }
    public int? Att { get; set; }
    public int? Def { get; set; }
    public int? Speed { get; set; }

    int ICommandQueryRetry.MaxRetries => 3;
}

ICommandQueryRetry will cause this to retry general exceptions up to 3 times before failing.

For caching, you just add a different interfaces (a few different ones for different timeframes) and it takes care of it for you.

public class ListQuery : IQuery<ICollection<ListDto>>, IQueryCacheableAbsoluteTimespan
{
    public string Name { get; set; }

    TimeSpan IQueryCacheableAbsoluteTimespan.ExpireTimeout => TimeSpan.FromDays(1);
}

CommandQueryHandler

public class CreateCommandQueryHandler : ICommandQueryHandler<CreateCommandQuery, int>
{
    private readonly IRepositoryMediator _repositoryMediator;

    public CreateCommandQueryHandler(IRepositoryMediator repositoryMediator) =>
        _repositoryMediator = repositoryMediator;

    public async Task<IResult<int>> ExecuteAsync(
        CreateCommandQuery commandQuery, CancellationToken token = default(CancellationToken))
    {
        var digimonId = await _repositoryMediator.ExecuteAsync<int>(commandQuery, token).ConfigureAwait(false);
        return ResultHelper.Successful(digimonId);
    }
}

Validation

The validation decorator will run validation on multiple threads (if you want) and async will not block. I didn’t use expressions since a lot of times validation involves multiple properties and has a lot of overhead. The BrokenRule() parameter is the “Relation” and it can be used to tie the rule somewhere on the UI.

public class CreateCommandQueryValidator : CommandQueryValidatorBase<CreateCommandQuery, int>
{
    private readonly IValidationRepositoryMediator _validationRepositoryMediator;
    private readonly IDigimonWorld2AdminResources _resources;

    public CreateCommandQueryValidator(IValidationRepositoryMediator validationRepositoryMediator,
        IDigimonWorld2AdminResources resources)
    {
        _validationRepositoryMediator = validationRepositoryMediator;
        _resources = resources;
    }

    protected override void CreateRules(CancellationToken token = default(CancellationToken))
    {
        AddRules(
            () => Validate.If(string.IsNullOrEmpty(CommandQuery.Name))?.BrokenRule(nameof(CommandQuery.Name))
                .Required(_resources.DigimonCreateCommandName),
            () => Validate.If(CommandQuery.DigimonTypeId == 0)?.BrokenRule(nameof(CommandQuery.DigimonTypeId))
                .Required(_resources.DigimonCreateCommandDigimonTypeId),
            () => Validate.If(CommandQuery.RankId == 0)?.BrokenRule(nameof(CommandQuery.RankId))
                .Required(_resources.DigimonCreateCommandRankId)
        );

        AddRules(_validationRepositoryMediator.GetValidationRules(CommandQuery, token));
    }
}

public class CreateCommandQueryValidationRepository : IValidationRepository<CreateCommandQuery>
{
    private readonly IValidator _validate;
    private readonly IDigimonWorld2ContextFactory _contextFactory;
    private readonly IDigimonWorld2AdminResources _resources;

    public CreateCommandQueryValidationRepository(IValidator validate, IDigimonWorld2ContextFactory contextFactory,
        IDigimonWorld2AdminResources resources)
    {
        _validate = validate;
        _contextFactory = contextFactory;
        _resources = resources;
    }

    public ICollection<Func<Task<BrokenRule>>> GetValidationRules(
        CreateCommandQuery request, CancellationToken token = default(CancellationToken)) =>
        new List<Func<Task<BrokenRule>>>(1)
        {
            async () =>
            {
                using (var context = _contextFactory.Create(false))
                {
                    return _validate.If(
                            !string.IsNullOrEmpty(request.Name) &&
                            await context.Digimons
                                .AnyAsync(a => a.Name.Equals(request.Name, StringComparison.OrdinalIgnoreCase),
                                    token)
                                .ConfigureAwait(false))?.BrokenRule(nameof(request.Name))
                        .AlreadyInUse(_resources.DigimonCreateCommandName, request.Name);
                }
            }
        };
}

Validation uses ?. here so that the second part isn’t run if there is no rule. .NET Core changed the way translations work, so I had to IoC inject a reference to them now, which is why you see that.

CreateCommandRepository

public class CreateCommandQueryRepository : IRepository<CreateCommandQuery, int>
{
    private const int ExpectedRowsAffected = 1;

    private readonly IDigimonWorld2ContextFactory _contextFactory;
    private readonly IMapperMediator _mapperMediator;

    public CreateCommandQueryRepository(
        IDigimonWorld2ContextFactory contextFactory,
        IMapperMediator mapperMediator)
    {
        _contextFactory = contextFactory;
        _mapperMediator = mapperMediator;
    }

    public async Task<int> ExecuteAsync(CreateCommandQuery request, CancellationToken token = default(CancellationToken))
    {
        using (var context = _contextFactory.Create())
        {
            var entity = _mapperMediator.Map<DigimonEntity>(request);
            context.Digimons.Add(entity);

            await context.SaveChangesAsync(ExpectedRowsAffected, token).ConfigureAwait(false);

            return entity.DigimonId;
        }
    }
}

My “repository” is a little different. The repository here is above the database technology being used. That way, if you want to change from EF to a webservice or something, you can change that implementation easily without affecting the handler above.

Mapper

public class CreateCommandQueryMapper : IMapper<CreateCommandQuery, DigimonEntity>
{
    public DigimonEntity Map(CreateCommandQuery command, DigimonEntity to = default(DigimonEntity))
    {
        to = to ?? new DigimonEntity();

        to.Name = command.Name;
        to.DigimonTypeId = command.DigimonTypeId;
        to.RankId = command.RankId;
        to.LearnedSkillId = command.LearnedSkillId;
        to.Att = command.Att;
        to.Def = command.Def;
        to.Found = command.Found;
        to.HasImage = command.HasImage;
        to.HP = command.HP;
        to.MP = command.MP;
        to.SpecialtyId = command.SpecialtyId;
        to.Speed = command.Speed;

        return to;
    }
}

I find if you do this in chunks together (all these classes, minus the controller) are all in the same folder as they are all related, that coding the mapping by hand isn’t that big of a deal. Though, I made this generic so you could setup your own that just used AutoMapper or whatever instead.

Invalidate Cache

public class CreateCommandQueryInvalidateCache : CacheManagerCommandQueryInvalidateCache<CreateCommandQuery, int>
{
    public CreateCommandQueryInvalidateCache(
        IQueryCacheRegion queryCacheRegion, 
        ICacheManager<object> cache) : base(queryCacheRegion, cache) { }

    protected override Task<ICollection<Type>> GetTypeOfQueriesToInvalidateAsync(
        CancellationToken token = default(CancellationToken)) =>
        Task.FromResult<ICollection<Type>>(new[] {typeof(ListQuery)});
}

If you know the queries you affect, you just have to give it the query type and it’ll take care of the rest. I made it async in case it took some IO to figure out all the types.

Decorators

The most important decorator I wanted to show was the exception handling one that is at the top of the chain:

public class CommandQueryHandlerExceptionDecorator<TCommandQuery, TResult> : ICommandQueryHandler<TCommandQuery, TResult>
    where TCommandQuery : ICommandQuery<TResult>
{
    private readonly ICommandQueryHandler<TCommandQuery, TResult> _commandQueryHandler;
    private readonly ILogger _logger;
    private readonly IUserContext _userContext;
    private readonly ICommonResource _resource;

    public CommandQueryHandlerExceptionDecorator(
        ICommandQueryHandler<TCommandQuery, TResult> commandQueryHandler, ILogger logger, IUserContext userContext,
        ICommonResource resource)
    {
        Guard.IsNotNull(commandQueryHandler, nameof(commandQueryHandler));
        Guard.IsNotNull(logger, nameof(logger));

        _commandQueryHandler = commandQueryHandler;
        _logger = logger;
        _userContext = userContext;
        _resource = resource;
    }

    public async Task<IResult<TResult>> ExecuteAsync(TCommandQuery commandQuery,
        CancellationToken token = default(CancellationToken))
    {
        try
        {
            return await _commandQueryHandler.ExecuteAsync(commandQuery, token).ConfigureAwait(false);
        }
        catch (UserFriendlyException ex)
        {
            await _logger.LogAsync(new LogEntry(LogTypeEnum.Error, _userContext,
                        "Friendly exception with command query: " + typeof(TCommandQuery).FullName, ex,
                        commandQuery),
                    token)
                .ConfigureAwait(false);
            return ResultHelper.Error<TResult>(ex.Message);
        }
        catch (DataNotFoundException ex)
        {
            await _logger.LogAsync(new LogEntry(LogTypeEnum.Error, _userContext,
                    "Data Not Found exception with command query: " + typeof(TCommandQuery).FullName, ex,
                    commandQuery), token)
                .ConfigureAwait(false);
            return ResultHelper.NoDataFoundError<TResult>();
        }
        catch (ConcurrencyException ex)
        {
            await _logger.LogAsync(new LogEntry(LogTypeEnum.Error, _userContext,
                        "Concurrency error with command query: " + typeof(TCommandQuery).FullName, ex,
                        commandQuery),
                    token)
                .ConfigureAwait(false);
            return ResultHelper.ConcurrencyError<TResult>();
        }
        catch (Exception ex)
        {
            await _logger.LogAsync(new LogEntry(LogTypeEnum.Error, _userContext,
                    "Error with command query: " + typeof(TCommandQuery).FullName, ex, commandQuery), token)
                .ConfigureAwait(false);
            return ResultHelper.Error<TResult>(_resource.ErrorGeneric);
        }
    }
}

If you are still reading and your eyes haven’t glazed over yet, what are your thoughts? Is this too much? Thanks!


Get this bounty!!!

#StackBounty: #java #oop #design-patterns #bytebuffer #srp Send data in multiple ways depending on how you want to send it

Bounty: 50

I have bunch of keys and values that I want to send to our messaging queue by packing them in one byte array. I will make one byte array of all the keys and values which should always be less than 50K and then send to our messaging queue.

Packet class:

public final class Packet implements Closeable {
  private static final int MAX_SIZE = 50000;
  private static final int HEADER_SIZE = 36;

  private final byte dataCenter;
  private final byte recordVersion;
  private final long address;
  private final long addressFrom;
  private final long addressOrigin;
  private final byte recordsPartition;
  private final byte replicated;
  private final ByteBuffer itemBuffer = ByteBuffer.allocate(MAX_SIZE);
  private int pendingItems = 0;

  public Packet(final RecordPartition recordPartition) {
    this.recordsPartition = (byte) recordPartition.getPartition();
    this.dataCenter = Utils.LOCATION.get().datacenter();
    this.recordVersion = 1;
    this.replicated = 0;
    final long packedAddress = new Data().packAddress();
    this.address = packedAddress;
    this.addressFrom = 0L;
    this.addressOrigin = packedAddress;
  }

  private void addHeader(final ByteBuffer buffer, final int items) {
    buffer.put(dataCenter).put(recordVersion).putInt(items).putInt(buffer.capacity())
        .putLong(address).putLong(addressFrom).putLong(addressOrigin).put(recordsPartition)
        .put(replicated);
  }

  private void sendData() {
    if (itemBuffer.position() == 0) {
      // no data to be sent
      return;
    }
    final ByteBuffer buffer = ByteBuffer.allocate(MAX_SIZE);
    addHeader(buffer, pendingItems);
    buffer.put(itemBuffer);
    SendRecord.getInstance().sendToQueueAsync(address, buffer.array());
    // SendRecord.getInstance().sendToQueueAsync(address, buffer.array());
    // SendRecord.getInstance().sendToQueueSync(address, buffer.array());
    // SendRecord.getInstance().sendToQueueSync(address, buffer.array(), socket);
    itemBuffer.clear();
    pendingItems = 0;
  }

  public void addAndSendJunked(final byte[] key, final byte[] data) {
    if (key.length > 255) {
      return;
    }
    final byte keyLength = (byte) key.length;
    final byte dataLength = (byte) data.length;

    final int additionalSize = dataLength + keyLength + 1 + 1 + 8 + 2;
    final int newSize = itemBuffer.position() + additionalSize;
    if (newSize >= (MAX_SIZE - HEADER_SIZE)) {
      sendData();
    }
    if (additionalSize > (MAX_SIZE - HEADER_SIZE)) {
      throw new AppConfigurationException("Size of single item exceeds maximum size");
    }

    final ByteBuffer dataBuffer = ByteBuffer.wrap(data);
    final long timestamp = dataLength > 10 ? dataBuffer.getLong(2) : System.currentTimeMillis();
    // data layout
    itemBuffer.put((byte) 0).put(keyLength).put(key).putLong(timestamp).putShort(dataLength)
        .put(data);
    pendingItems++;
  }

  @Override
  public void close() {
    if (pendingItems > 0) {
      sendData();
    }
  }
}

Below is the way I am sending data. As of now my design only permits to send data asynchronously by calling sendToQueueAsync method in above sendData() method.

  private void validateAndSend(final RecordPartition partition) {
    final ConcurrentLinkedQueue<DataHolder> dataHolders = dataHoldersByPartition.get(partition);

    final Packet packet = new Packet(partition);

    DataHolder dataHolder;
    while ((dataHolder = dataHolders.poll()) != null) {
      packet.addAndSendJunked(dataHolder.getClientKey().getBytes(StandardCharsets.UTF_8),
          dataHolder.getProcessBytes());
    }
    packet.close();
  }

Now I need to extend my design so that I can send data in three different ways. It is upto user to decide which way he wants to send data to either “sync” or “async”.

  • I need to send data asynchronously by calling sender.sendToQueueAsync method.
  • or I need to send data synchronously by calling sender.sendToQueueSync method.
  • or I need to send data synchronously but on a particular socket by calling sender.sendToQueueSync method. In this case I need to pass socket variable somehow so that sendData knows about this variable.

SendRecord class:

public class SendRecord {
  private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);
  private final Cache<Long, PendingMessage> cache = CacheBuilder.newBuilder().maximumSize(1000000)
      .concurrencyLevel(100).build();

  private static class Holder {
    private static final SendRecord INSTANCE = new SendRecord();
  }

  public static SendRecord getInstance() {
    return Holder.INSTANCE;
  }

  private SendRecord() {
    executorService.scheduleAtFixedRate(new Runnable() {
      @Override
      public void run() {
        handleRetry();
      }
    }, 0, 1, TimeUnit.SECONDS);
  }

  private void handleRetry() {
    List<PendingMessage> messages = new ArrayList<>(cache.asMap().values());
    for (PendingMessage message : messages) {
      if (message.hasExpired()) {
        if (message.shouldRetry()) {
          message.markResent();
          doSendAsync(message);
        } else {
          cache.invalidate(message.getAddress());
        }
      }
    }
  }

  // called by multiple threads concurrently
  public boolean sendToQueueAsync(final long address, final byte[] encodedRecords) {
    PendingMessage m = new PendingMessage(address, encodedRecords, true);
    cache.put(address, m);
    return doSendAsync(m);
  }

  // called by above method and also by handleRetry method
  private boolean doSendAsync(final PendingMessage pendingMessage) {
    Optional<SocketHolder> liveSocket = SocketManager.getInstance().getNextSocket();
    ZMsg msg = new ZMsg();
    msg.add(pendingMessage.getEncodedRecords());
    try {
      // this returns instantly
      return msg.send(liveSocket.get().getSocket());
    } finally {
      msg.destroy();
    }
  }

  // called by send method below
  private boolean doSendAsync(final PendingMessage pendingMessage, final Socket socket) {
    ZMsg msg = new ZMsg();
    msg.add(pendingMessage.getEncodedRecords());
    try {
      // this returns instantly
      return msg.send(socket);
    } finally {
      msg.destroy();
    }
  }

  // called by multiple threads to send data synchronously without passing socket
  public boolean sendToQueueSync(final long address, final byte[] encodedRecords) {
    PendingMessage m = new PendingMessage(address, encodedRecords, false);
    cache.put(address, m);
    try {
      if (doSendAsync(m)) {
        return m.waitForAck();
      }
      return false;
    } finally {
      cache.invalidate(address);
    }
  }

  // called by a threads to send data synchronously but with socket as the parameter
  public boolean sendToQueueSync(final long address, final byte[] encodedRecords, final Socket socket) {
    PendingMessage m = new PendingMessage(address, encodedRecords, false);
    cache.put(address, m);
    try {
      if (doSendAsync(m, socket)) {
        return m.waitForAck();
      }
      return false;
    } finally {
      cache.invalidate(address);
    }
  }

  public void handleAckReceived(final long address) {
    PendingMessage record = cache.getIfPresent(address);
    if (record != null) {
      record.ackReceived();
      cache.invalidate(address);
    }
  }
}

Callers will only call either of below three methods:

  • sendToQueueAsync by passing two parameters
  • sendToQueueSync by passing two parameters
  • sendToQueueSync by passing three parameters

How should I design my Packet and SendRecord class so that I can tell Packet class that this data needs to be send in either of above three ways to my messaging queue. It is upto user to decide which way he wants to send data to messaging queue. As of now the way my Packet class is structured, it can send data only in one way.


Get this bounty!!!

#StackBounty: #java #multithreading #design-patterns #thread-safety #atomicity Release a socket back depending on whether they are live…

Bounty: 50

I am using below class to send data to our messaging queue by using socket either synchronously or asynchronously as shown below. It depends on requirement whether I want to call synchronous or asynchronous method to send data on a socket. Most of the times we will send data asynchronously but sometimes I may need to send data synchronously.

  • sendAsync – It sends data asynchronously and we don’t block the thread. If acknowledgment is not received then it will retry again from the background thread which is started in SendToQueue constructor only.
  • send – It sends data synchronously on a socket. It internally calls doSendAsync method and then sleep for a particular timeout period and if acknowledgment is not received then it removes from cache bucket so that we don’t retry again.

So the only difference between those two above methods is – For async case, I need to retry at all cost if acknowledgment is not received but for sync I don’t need to retry at all and that’s why I am storing more state in a PendingMessage class.

ResponsePoller is a class which receives the acknowledgment for the data that was sent to our messaging queue on a particular socket and then calls handleAckReceived method below to remove the address so that we don’t retry after receiving the acknowledgment. If acknowledgment is received then socket is live otherwise it is dead.

public class SendToQueue {
  private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);
  private final Cache<Long, PendingMessage> cache = CacheBuilder.newBuilder()
          .maximumSize(1000000)
          .concurrencyLevel(100)
          .build();

  private static class PendingMessage {
    private final long _address;
    private final byte[] _encodedRecords;
    private final boolean _retryEnabled;
    private final Object _monitor = new Object();
    private long _sendTimeMillis;
    private volatile boolean _acknowledged;

    public PendingMessage(long address, byte[] encodedRecords, boolean retryEnabled) {
      _address = address;
      _sendTimeMillis = System.currentTimeMillis();
      _encodedRecords = encodedRecords;
      _retryEnabled = retryEnabled;
    }

    public synchronized boolean hasExpired() {
      return System.currentTimeMillis() - _sendTimeMillis > 500L;
    }

    public synchronized void markResent() {
      _sendTimeMillis = System.currentTimeMillis();
    }

    public boolean shouldRetry() {
      return _retryEnabled && !_acknowledged;
    }

    public boolean waitForAck() {
      try {
        synchronized (_monitor) {
          _monitor.wait(500L);
        }
        return _acknowledged;
      } catch (InterruptedException ie) {
        return false;
      }
    }

    public void ackReceived() {
      _acknowledged = true;
      synchronized (_monitor) {
        _monitor.notifyAll();
      }
    }

    public long getAddress() {
      return _address;
    }

    public byte[] getEncodedRecords() {
      return _encodedRecords;
    }
  }

  private static class Holder {
    private static final SendToQueue INSTANCE = new SendToQueue();
  }

  public static SendToQueue getInstance() {
    return Holder.INSTANCE;
  }

  private void handleRetries() {
    List<PendingMessage> messages = new ArrayList<>(cache.asMap().values());
    for (PendingMessage m : messages) {
      if (m.hasExpired()) {
        if (m.shouldRetry()) {
          m.markResent();
          doSendAsync(m);
        } else {
          cache.invalidate(m.getAddress());
        }
      }
    }
  }

  private SendToQueue() {
    executorService.submit(new ResponsePoller()); // another thread which receives acknowledgment
                                                  // and then delete entry from the cache
                                                  // accordingly.
    executorService.scheduleAtFixedRate(new Runnable() {
      @Override
      public void run() {
        handleRetries();
      }
    }, 0, 1, TimeUnit.SECONDS);
  }

  public boolean sendAsync(final long address, final byte[] encodedRecords) {
    PendingMessage m = new PendingMessage(address, encodedRecords, true);
    cache.put(address, m);
    return doSendAsync(m);
  }

  private boolean doSendAsync(final PendingMessage pendingMessage) {
    Optional<SocketHolder> liveSocket = SocketManager.getInstance().getNextSocket();
    ZMsg msg = new ZMsg();
    msg.add(pendingMessage.getEncodedRecords());
    try {
      return msg.send(liveSocket.get().getSocket());
    } finally {
      msg.destroy();
    }
  }

  public boolean send(final long address, final byte[] encodedRecords) {
    PendingMessage m = new PendingMessage(address, encodedRecords, false);
    cache.put(address, m);
    try {
      if (doSendAsync(m)) {
        return m.waitForAck();
      }
      return false;
    } finally {
      cache.invalidate(address);
    }
  }

  // called by acknowledgment thread which is in "ResponsePoller" class
  public void handleAckReceived(final long address) {
    PendingMessage m = cache.getIfPresent(address);
    if (m != null) {
      m.ackReceived();
      cache.invalidate(address);
    }
  }
}

As I am sending data on a socket and if I get the acknowledgment back for the same data then it means Socket is alive but if data is not acknowledge back then it means socket is dead (but I will keep retrying to send the data). So with my above design (or if there is any better way), how can I figure out whether any socket is dead or live because either acknowledgment was not received or it was received from that socket and basis on that I need to release the socket back into its pool (whether it is alive or dead) by calling below method depending on whether acknowledgment is received or not either for sync or async case.

I also need to configure count that if acknowledgment is not received on a particular socket for x (where x is a number > 0, default should be 2) times, then only mark a socket dead. What is the best and efficient way to do this thing?

SocketManager.getInstance().releaseSocket(socket, SocketState.LIVE);
SocketManager.getInstance().releaseSocket(socket, SocketState.DEAD);


Get this bounty!!!

#StackBounty: #python #design-patterns #recursion #backtracking #visitor-pattern A KenKen puzzle/solver in Python

Bounty: 200

I’ve written a simple KenKen puzzle/solver in Python. I’d love some feedback on the design of the puzzle, as well as the architecture for the solver.

To model the puzzle, I have the following classes:

  • Cell is used to model a (row, col, value) tuple
  • Cage (abstract) is used to model a grouping of Cell objects that must collectively satisfy a constraint. From this class, we have the following derived classes:
    • AddCage for cells involved in addition constraints
    • MulCage for cells involved in multiplication constraints
    • SubCage for cells involved in subtraction constraints
    • DivCage for cells involved in division constraints
    • ConCage for constant constraints
    • RowCage for unique row/column constraints
  • Puzzle combines cages, cells, and exposes methods for the unassigned cells, whether or not the puzzle is solved, etc.

Now for the code:

from abc import ABC, abstractmethod
from utils import kk_add, kk_mul, kk_sub, kk_div


class Cell:
    def __init__(self, row, col, value=None):
        """
        Models a cell in a kenken puzzle

        Args:
            row: row
            col: column
            value: cell value

        """

        self.row = row
        self.col = col
        self.value = value

    def __str__(self):
        return '<Cell ({0}, {1}): {2}>'.format(self.row, self.col, self.value)

    def __hash__(self):
        return hash((self.row, self.col))

    def accept(self, visitor):
        """
        Visitor implementation; accept a visitor object
        and call the object's visit method for this object

        Args:
            visitor: `CellVisitor` implementation 

        Returns: None
        """
        visitor.visit_cell(self)


class Cage(ABC):
    def __init__(self, cells, func):
        """
        Base class to model a cage in a kenken puzzle

        A cage is a grouping of cells with a constraint
        that the values of the cells must collectively satisfy

        Args:
            cells: the `Cell` objects in this cage
            func: a predicate used to indicate when the cage is satisfied

        """

        self.cells = set(cells)
        self.func = func

    def __str__(self):
        return '<{0} cells={1}>'.format(self.__class__.__name__, self.cells)

    @property
    def values(self):
        """ 
        Returns: list the cell values list for this cage
        """
        return [cell.value for cell in self.cells]

    @property
    def consistent(self):
        """
        Returns: bool whether or not this cage is consistent
        with respect to its current cell values
        """
        return None in self.values or self.solved

    @property
    def solved(self):
        """
        Returns: bool whether or not this cage is solved
        with respect to its current cell values
        """

        values = self.values
        return (
            None not in values
            and len(values) == len(self.cells)
            and self.evaluate(*values)
        )

    def evaluate(self, *values):
        """
        Evaluate this cage for the given input arguments,
        returning whether or not it's conditions have been satisfied

        Args:
            *values: variate list of test values

        Returns: bool
        """
        return self.func(values)

    @abstractmethod
    def accept(self, visitor):
        """
        Visit this cage. Accept a visitor object and call the
        object's visit method for this object

        Args:
            visitor: `CageVisitor` implementation 

        Returns: None
        """
        pass


class AddCage(Cage):
    def __init__(self, cells, value):
        """
        Models an addition cage in a kenken puzzle

        Args:
            cells: list of `Cell` objects contained in this cage
            value: target value the cell values in this cage must sum to

        """

        self.value = value
        super().__init__(cells, lambda values: kk_add(values, value))

    def accept(self, visitor):
        """
        Visit this cage

        Args:
            visitor: `CageVisitor` object

        Returns: None
        """
        visitor.visit_add(self)


class MulCage(Cage):
    def __init__(self, cells, value):
        """
        Models a multiplication cage in a kenken puzzle

        Args:
            cells: list of `Cell` objects contained in this cage
            value: target value the cell values in this cage must multiply to

        """

        self.value = value
        super().__init__(cells, lambda values: kk_mul(values, value))

    def accept(self, visitor):
        """
        Visit this cage

        Args:
            visitor: `CageVisitor` object

        Returns: None
        """
        visitor.visit_mul(self)


class SubCage(Cage):
    def __init__(self, cells, value):
        """
        Models a subtraction cage in a kenken puzzle

        Args:
            cells: list of `Cell` objects contained in this cage
            value: target value the cell values in this cage must subtract to

        """

        self.value = value
        super().__init__(cells, lambda values: kk_sub(values, value))

    def accept(self, visitor):
        """
        Visit this cage

        Args:
            visitor: `CageVisitor` object

        Returns: None
        """
        visitor.visit_sub(self)


class DivCage(Cage):
    def __init__(self, cells, value):
        """
        Models a division cage in a kenken puzzle

        Args:
            cells: list of `Cell` objects contained in this cage
            value: target value the cell values in this cage must divide to

        """

        self.value = value
        super().__init__(cells, lambda values: kk_div(values, value))

    def accept(self, visitor):
        """
        Visit this cage

        Args:
            visitor: `CageVisitor` object

        Returns: None
        """
        visitor.visit_div(self)


class ConCage(Cage):
    def __init__(self, cell, value):
        """
        Models a constant cage in a kenken puzzle

        Args:
            cell: `Cell` object for this cage
            value: target value

        """

        def func(values):
            return len(values) == 1 and values[0] == value

        self.value = value
        super().__init__([cell], func)

    def accept(self, visitor):
        """
        Visit this cage

        Args:
            visitor: `CageVisitor` object

        Returns: None
        """
        visitor.visit_con(self)


class RowCage(Cage): # RowConstraint
    def __init__(self, cells):
        """
        Models a row constraint in a kenken puzzle

        Here the cell values in this cage must be all unique
        for the cage to be solved

        Args:
            cells: `Cell` objects

        """

        def func(values):
            return len(values) == len(set(values))

        super().__init__(cells, func)

    def accept(self, visitor):
        """
        Visit this cage

        Args:
            visitor: `CageVisitor` object

        Returns: None
        """
        visitor.visit_row(self)


class Puzzle:
    def __init__(self, width, cells, cages):
        """
        Models a kenken puzzle

        See https://en.wikipedia.org/wiki/KenKen
        for more information

        Args:
            width: puzzle size
            cells: `Cell` objects comprising this puzzle
            cages: `Cage` objects a solution for this puzzle must satisfy

        """

        self.width = width
        self.cells = cells
        self.cages = cages

    def __str__(self):
        return '<Puzzle width={0}, cages={1}>'.format(
            self.width, len(self.cages)
        )

    @property
    def domain(self):
        """
        Returns: bool this puzzle's possible cells values
        """
        return range(1, self.width + 1)

    @property
    def unassigned(self):
        """
        Returns: bool this puzzle's unassigned cells
        """
        return (cell for cell in self.cells if cell.value is None)

    @property
    def solved(self):
        """
        Returns: bool whether or not this puzzle has been solved
        """
        return all(cage.solved for cage in self.cages)

    def consistent(self, cell):
        """
        Returns whether or not the value for the given cell is consistent
        with all of its cage constraints

        Args:
            cell: `Cell` object

        Returns: bool

        """

        return all(cage.consistent for cage in self.cages if cell in cage.cells)

For both the Cell and the Cage classes, we have an accept method. This is used to make the objects amenable to the visitor design pattern, for use during solving. The idea is that each cell has a set of “candidate values” that needs to be reduced after we decide to place a value for the cell. I decided to expose things this way to make edits to the core puzzle logic less frequent. Moreover, to try different solution strategies, we need only change the implementation of the visitor we pass to the cells/cages; the core puzzle components need not be changed.

Let’s look at the solver classes:

  • CellVisitor is used to visit cells
  • CageVisitor is used to visit cages; its lifetime is managed by a CellVisitor

And the code:

from utils import with_timing, kk_div, kk_sub


class CellVisitor:
    def __init__(self, candidates, cages):
        """
        Visitor for puzzle cells

        Pass an instance of this object to a puzzle cell
        to "visit" the cell and all the cages that involve
        this cell

        Here we use this object to model the process of eliminating
        a set of candidate values for the given cell

        See https://en.wikipedia.org/wiki/Visitor_pattern
        for more information on this design pattern

        Args:
            candidates: list of cell candidates
            cages: list of cages this visitor should also visit

        """

        self.candidates = candidates
        self.cages = cages

    def __str__(self):
        return '<CellVisitor candidates={0}>'.format(self.candidates)

    def visit_cell(self, cell):
        """
        Visits a `Cell`

        Visit each cage that contains this cell; the resulting
        candidates will be the possible values for this cell

        Args:
            cell: `Cell` object to visit

        Returns: None

        """
        visitor = CageVisitor(self.candidates)
        for cage in self.cages:
            cage.accept(visitor)


class CageVisitor:
    def __init__(self, candidates):
        """
        Visitor for puzzle cages

        The methods in this object are used to prune the cell
        candidate values

        Args:
            candidates: cell candidate values to prune

        """

        self.candidates = candidates

    def __str__(self):
        return '<CageVisitor candidates={0}>'.format(self.candidates)

    def visit_add(self, cage):
        """
        Visits an `AddCage`

        We start with the current cage sum. Any
        value that exceeds the cage target value is pruned

        Args:
            cage: `AddCage` object to visit

        Returns: None

        """
        s = sum(value for value in cage.values if value)
        for value in self.candidates[:]:
            if value + s > cage.value:
                self.prune(value)

    def visit_mul(self, cage):
        """
        Visits a `MulCage`

        Any candidate value that is not a divisor of
        the cage target value is pruned

        Args:
            cage: `MulCage` object to visit

        Returns: None

        """
        for value in self.candidates[:]:
            if cage.value % value != 0:
                self.prune(value)

    def visit_sub(self, cage):
        """
        Visits a `SubCage`

        This implementation removes pairs from the
        candidates if the difference of a given pair
        is not equal to the cage value

        Args:
            cage: `MulCage` object to visit

        Returns: None

        """
        candidates = self.candidates[:]
        for x in candidates:
            if not any(kk_sub([x, y], cage.value) for y in candidates):
                self.prune(x)

    def visit_div(self, cage):
        """
        Visits a `DivCage`

        This implementation removes pairs from the
        candidates if the quotient of a given pair
        is not equal to the cage value

        Args:
            cage: `DivCage` object to visit

        Returns: None

        """
        candidates = self.candidates[:]
        for x in candidates:
            if not any(kk_div([x, y], cage.value) for y in candidates):
                self.prune(x)

    def visit_con(self, cage):
        """
        Visits a `ConCage`

        This implementation removes all candidates
        that are not equal to the cage target value

        Args:
            cage: `ConCage` object to visit

        Returns: None

        """
        for x in self.candidates[:]:
            if x != cage.value:
                self.prune(x)

    def visit_row(self, cage):
        """
        Visits a `RowCage`

        This implementation removes all values
        that are already assigned to a cell in the row

        Args:
            cage: `ConCage` object to visit

        Returns: None

        """
        for value in cage.values:
            self.prune(value)

    def prune(self, value):
        """
        Helper method to safely remove values
        from the candidates

        Args:
            value: to remove

        Returns: None

        """
        if value in self.candidates:
            self.candidates.remove(value)


@with_timing
def backtrack_solve(puzzle):
    """
    Solves a kenken puzzle recursively

    During each iteration of the algorithm, a filtering
    strategy is applied to the puzzle's remaining unassigned cells

    See https://en.wikipedia.org/wiki/Backtracking
    for more information on this algorithm

    Args:
        puzzle: `Puzzle` object to solve

    Returns: bool True if all values in `puzzle` have been assigned a value

    """

    def reduce(cell):
        """
        Reduce the candidate values for this cell

        Args:
            cell: `Cell` object to reduce

        Returns: list of reduced candidates

        """

        candidates = list(puzzle.domain)
        cages = (cage for cage in puzzle.cages if cell in cage.cells)
        cell.accept(CellVisitor(candidates, cages))
        return candidates

    def solve():
        """
        Solve this puzzle recursively

        The algorithm first reduces the candidates for the puzzle's
        unassigned cells

        We then sort the reduced cells by candidate length and
        recursively try values for the current cell until the search
        successfully solves the puzzle

        Returns: bool

        """

        reduced = {cell: reduce(cell) for cell in puzzle.unassigned}

        for cell in sorted(reduced, key=lambda c: len(reduced[c])):
            for value in reduced[cell]:
                cell.value = value

                if puzzle.consistent(cell):
                    if solve():
                        return True

                cell.value = None

            return False
        return puzzle.solved
    return solve()

You can read more about the algorithm in the documentation for the solver. The basic idea is that when we visit a cell, we start off with the puzzle’s full domain. Each of the cages reduces the candidates further, by means of a filtering strategy that is invoked on the candidates when we visit that cage. We do this “reduce” operation for each of the unassigned cells.

Finally, I have a “utils.py” that contains definitions that are in use by the solver and puzzle files. Included is a parse_string method that can be used to create a Puzzle object from a dictionary string:

import time

from ast import literal_eval
from functools import wraps, reduce


def kk_add(values, value):
    """
    Returns whether or not the given values
    sum to the target value

    Args:
        values: list of test values
        value: target value

    Returns: bool

    """
    return sum(values) == value


def kk_mul(values, value):
    """
    Returns whether or not the given values
    multiply to the target value

    Args:
        values: list of test values
        value: target value

    Returns: bool

    """
    return product(values) == value


def kk_sub(values, value):
    """
    Returns whether or not the given values subtract
    to the target value

    Args:
        values: list of test values
        value: target value

    Returns: bool

    """
    return abs(values[0] - values[1]) == value


def kk_div(values, value):
    """
    Returns whether or not the given values divide
    to the target value

    Args:
        values: list of test values
        value: target value

    Returns: bool

    """
    return (int(values[0] / values[1]) == value or
            int(values[1] / values[0]) == value)


def product(nums):
    """
    Helper method to compute the product of a list
    of numbers

    Args:
        nums: list of numbers

    Returns: number

    """
    return reduce(lambda x, y: x * y, nums, 1)


def with_timing(f, output=print):
    """
    Helper method to run a function and output
    the function run time

    Args:
        f: function to decorate
        output: function to output the time message

    Returns: callable decorated function

    """
    @wraps(f)
    def timed(*args, **kwargs):
        ts = time.time()
        result = f(*args, **kwargs)
        te = time.time()

        message = 'func:{!r} args:[{!r}, {!r}] took: {:2.4f} sec'.format(
            f.__name__, args, kwargs, te - ts
        )

        output(message)

        return result
    return timed


def parse_string(s):
    """
    Parse a string to a `Puzzle` object

    The string should be a dictionary that python
    can interpret literally. For example:

    {
      'size': 2,
       'cages': [
         {'value': 2, 'op': '/', 'cells': [(0,0), (0,1)]},
         {'value': 3, 'op': '+', 'cells': [(1,0), (1,1)]}
      ]
    }

    The 'op' should be one of :

        '+' -> AddCage,
        '-' -> SubCage,
        '*' -> MulCage,
        '/' -> DivCage,
        '$' -> ConCage

    The exclusive row/column cages will be created automatically

    Args:
        s: input string to read

    Returns: `Puzzle` object

    """

    from puzzle import (
        Cell,
        AddCage,
        SubCage,
        MulCage,
        DivCage,
        ConCage,
        RowCage,
        Puzzle
    )

    d = literal_eval(s.strip())

    cage_factory = {
        '+': AddCage,
        '-': SubCage,
        '*': MulCage,
        '/': DivCage,
        '$': ConCage
    }

    size = d.get('size')
    cages = d.get('cages')

    if size is None or cages is None:
        raise SyntaxError(
            "Expected 'size' and 'cages'. Got `{0}`".format(d)
        )

    puzzle_cages = []
    puzzle_cells = set()

    for cage in cages:
        value = cage.get('value')
        cells = cage.get('cells')

        if any(cell in puzzle_cells for cell in cells):
            raise ValueError('Some cells exist in another cage {0}'.format(cells))

        if not value or not cells:
            raise SyntaxError(
                "Expected 'value' and 'cells'. Got {0}".format(cage)
            )

        op = cage.get('op')

        if op not in cage_factory:
            raise SyntaxError(
                "Expected '+', '-', '*', '/', '$'. Got {0}".format(op)
            )

        if op == '$' and len(cells) > 1:
            raise ValueError("Expected one cell for `ConstantConstraint`")

        cage_cells = []
        for (row, col) in cells:
            cell = Cell(row, col, None)
            cage_cells.append(cell)

        puzzle_cells = puzzle_cells.union(cage_cells)

        # the constructor for `ConCage` expects a single cell as oppose to a list
        cage = cage_factory[op](cage_cells[0] if op == '$' else cage_cells, value)
        puzzle_cages.append(cage)

    if len(puzzle_cells) != size * size:
        raise Exception(
            'Expected {0} cells; parsed {1}'.format(
                size*size, puzzle_cells)
        )

    for row in range(size):
        cells = [cell for cell in puzzle_cells if cell.row == row]
        puzzle_cages.append(RowCage(cells))

    for col in range(size):
        cells = [cell for cell in puzzle_cells if cell.col == col]
        puzzle_cages.append(RowCage(cells))

    return Puzzle(size, puzzle_cells, puzzle_cages)

Any feedback is welcome. I have some additional puzzle files that I used while debugging/testing the solving algorithm, as well as a “run.py” file which provides a CLI for this application. If you think this is needed, feel free to leave a comment and I can provide a link.


Get this bounty!!!

#StackBounty: #java #design-patterns #mvc Is this a correct implementation of Trygve Reenskaug 's MVC specification?

Bounty: 100

So I was reading the MODELS – VIEWS – CONTROLLERS paper by Trygve Reenskaug from December 1979 and wanted to try an implementation with Java Swing from my understandings..

Notes I have taken are as follows:

A view is attached to its model (or model part) and gets the data
necessary for the presentation from the model by asking questions. It
may also update the model by sending appropriate messages. All these
questions and messages have to be in the terminology of the model, the
view will therefore have to know the semantics of the attributes of
the model it represents.

A view should never know about user input, such as mouse operations
and keystrokes. It should always be possible to write a method in a
controller that sends messages to views which exactly reproduce any
sequence of user commands.

A Controller provides means for user input by presenting the user with
menus or other means of giving commands and data. The controller
receives such user input, translates it into the appropriate messages
and pass these messages onto one or more of the views.

The application I worked on is a very simple Note Taking application. This is what the application itself looks like:

enter image description here
enter image description here
enter image description here

Moving on the code, start with Directory Layout..enter image description here

My Model is very simple and knows nothing about Views or Controllers..

package biz.tugay.swingynotes.model;

/* User: koray@tugay.biz Date: 2017/05/12 */
public class SwingyNote {

    private final String note;

    public SwingyNote(final String note) {
        this.note = note;
    }

    public String getNote() {
        return note;
    }
}

package biz.tugay.swingynotes.model;

import java.util.*;

/* User: koray@tugay.biz Date: 2017/05/12 */
public final class SwingyNoteService {

    private final Set<SwingyNote> swingyNotes = new HashSet<SwingyNote>();

    // Add some sample data..
    {
        final SwingyNote sampleNote = new SwingyNote("Sample Note!");
        addNote(sampleNote);

        final SwingyNote helloWorld = new SwingyNote("Hello World!");
        addNote(helloWorld);
    }

    public void addNote(final SwingyNote swingyNote) {
        swingyNotes.add(swingyNote);
    }

    public Collection<SwingyNote> getAllNotes() {
        return swingyNotes;
    }
}

Moving on to View..

package biz.tugay.swingynotes.view;

import javax.swing.*;
import java.awt.*;

/* User: koray@tugay.biz Date: 2017/05/12 */
public class SwingyNotesMainFrame extends JFrame {

    public SwingyNotesMainFrame(final AllNotesPanel allNotesPanel, final AddNewNotePanel addNewNotePanel) {
        super("Swingy Notes");

        // Set Layout..
        final BorderLayout borderLayout = new BorderLayout();
        final Container contentPane = getContentPane();
        contentPane.setLayout(borderLayout);

        // Add panels..
        contentPane.add(allNotesPanel, BorderLayout.CENTER);
        contentPane.add(addNewNotePanel, BorderLayout.SOUTH);

        // Adjust properties and make the frame visible..
        setSize(600, 200);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setVisible(true);
    }
}

package biz.tugay.swingynotes.view;

import biz.tugay.swingynotes.model.SwingyNote;
import biz.tugay.swingynotes.model.SwingyNoteService;

import javax.swing.*;
import java.awt.*;
import java.util.Collection;

/* User: koray@tugay.biz Date: 2017/05/12 */
public class AllNotesPanel extends JPanel {

    private final SwingyNoteService swingyNoteService;

    public AllNotesPanel(final SwingyNoteService swingyNoteService) {
        this.swingyNoteService = swingyNoteService;
        displayAllNotes();
    }

    public void displayAllNotes() {
        removeAll();
        final Collection<SwingyNote> allNotes = swingyNoteService.getAllNotes();
        for (final SwingyNote swingyNote : allNotes) {
            final JLabel swingyNoteLabel = buildLabelForSwingyNote(swingyNote);
            add(swingyNoteLabel);
        }
        validate();
        repaint();
    }

    private JLabel buildLabelForSwingyNote(final SwingyNote swingyNote) {
        final JLabel swingyNoteLabel = new JLabel(swingyNote.getNote());
        swingyNoteLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
        swingyNoteLabel.setFont(new Font("Dialog", Font.BOLD, 27));
        swingyNoteLabel.setOpaque(true);
        swingyNoteLabel.setBackground(Color.YELLOW);
        return swingyNoteLabel;
    }
}

package biz.tugay.swingynotes.view;

import biz.tugay.swingynotes.model.SwingyNote;
import biz.tugay.swingynotes.model.SwingyNoteService;

import javax.swing.*;

/* User: koray@tugay.biz Date: 2017/05/12 */
public class AddNewNotePanel extends JPanel {

    private final SwingyNoteService swingyNoteService;
    private final JTextField newNoteInputTextField;

    public AddNewNotePanel(final SwingyNoteService swingyNoteService) {
        this.swingyNoteService = swingyNoteService;
        this.newNoteInputTextField = new JTextField(20);

        add(newNoteInputTextField);
    }

    public void addNote() {
        final SwingyNote swingyNote = new SwingyNote(newNoteInputTextField.getText());
        swingyNoteService.addNote(swingyNote);
        newNoteInputTextField.setText(null);
    }
}

and here is my Controller

package biz.tugay.swingynotes.controller;

import biz.tugay.swingynotes.view.AddNewNotePanel;
import biz.tugay.swingynotes.view.AllNotesPanel;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/* User: koray@tugay.biz Date: 2017/05/12 */
public class AddNewNoteButton extends JButton implements ActionListener {

    private final AddNewNotePanel addNewNotePanel;
    private final AllNotesPanel allNotesPanel;

    public AddNewNoteButton(final AddNewNotePanel addNewNotePanel, final AllNotesPanel allNotesPanel) {
        super("Add New Note!");
        addActionListener(this);

        this.addNewNotePanel = addNewNotePanel;
        this.allNotesPanel = allNotesPanel;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        addNewNotePanel.addNote();
        allNotesPanel.displayAllNotes();
    }
}

and this is how I start my Application:

package biz.tugay.swingynotes;

import biz.tugay.swingynotes.controller.AddNewNoteButton;
import biz.tugay.swingynotes.model.SwingyNoteService;
import biz.tugay.swingynotes.view.AllNotesPanel;
import biz.tugay.swingynotes.view.AddNewNotePanel;
import biz.tugay.swingynotes.view.SwingyNotesMainFrame;

import javax.swing.*;

/* User: koray@tugay.biz Date: 2017/05/12 */
public class App {

    public static void main(String[] args) {

        // Model..
        final SwingyNoteService swingyNoteService = new SwingyNoteService();

        // View..
        final AllNotesPanel allNotesPanel = new AllNotesPanel(swingyNoteService);
        final AddNewNotePanel addNewNotePanel = new AddNewNotePanel(swingyNoteService);

        // Controller..
        final AddNewNoteButton addNewNoteButton = new AddNewNoteButton(addNewNotePanel, allNotesPanel);
        addNewNotePanel.add(addNewNoteButton);

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new SwingyNotesMainFrame(allNotesPanel, addNewNotePanel);
            }
        });
    }
}

Do all components seem to be correct?


Get this bounty!!!